From 8744c0d5fdca5daab55d35e866c667328527ed8a Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Wed, 31 May 2023 15:47:19 -0300 Subject: [PATCH 01/31] [Infrastructure UI] Asset Details - Centralize storybook decorator and enforce types (#158719) Part of: [#156696](https://github.com/elastic/kibana/issues/156696) ## Summary The aim of this PR is to facilitate the inclusion of new storybooks by centralizing the necessary mocks. Besides, it changes the current approach to structuring the storybook. **previous** image **now** without _Anomalies_ image The `Components` folder contains all variations of each component that can be used in the asset details, instead of mixing it with the now removed `Asset Details Embeddable`. The `Asset Details Embeddable` was removed, but the main storybooks were kept, `Page` and `Flyout` which display the full content, composed of the existing tabs - but without variations ### How to test - run `yarn storybook infra` --- .../__stories__/context/fixtures/anomalies.ts | 39 +++ .../__stories__/context/fixtures/metadata.ts | 74 ++++++ .../__stories__/context/fixtures/processes.ts | 127 ++++++++++ .../asset_details/__stories__/context/http.ts | 38 +++ .../asset_details/__stories__/decorator.tsx | 83 +++++++ .../asset_details/asset_details.stories.tsx | 116 ++++----- .../asset_details.story_decorators.tsx | 222 ------------------ .../links/link_to_apm_services.stories.tsx | 35 +-- .../links/link_to_uptime.stories.tsx | 34 +-- .../asset_details/tab_content/tab_content.tsx | 2 +- .../tabs/metadata/metadata.stories.tsx | 77 ++++++ .../tabs/metadata/table.stories.tsx | 129 ---------- .../asset_details/tabs/metadata/table.tsx | 2 +- .../tabs/processes/processes.stories.tsx | 57 ++--- .../processes/processes.story_decorators.tsx | 161 ------------- .../tabs/processes/processes.tsx | 168 +++++++------ .../inventory_view/hooks/use_process_list.ts | 8 +- 17 files changed, 617 insertions(+), 755 deletions(-) create mode 100644 x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/anomalies.ts create mode 100644 x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/metadata.ts create mode 100644 x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/processes.ts create mode 100644 x-pack/plugins/infra/public/components/asset_details/__stories__/context/http.ts create mode 100644 x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx delete mode 100644 x-pack/plugins/infra/public/components/asset_details/asset_details.story_decorators.tsx create mode 100644 x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.stories.tsx delete mode 100644 x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.stories.tsx delete mode 100644 x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.story_decorators.tsx diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/anomalies.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/anomalies.ts new file mode 100644 index 0000000000000..d4f2d3f11e43d --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/anomalies.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { GetMetricsHostsAnomaliesSuccessResponsePayload } from '../../../../../../common/http_api/infra_ml'; + +const anomalies: GetMetricsHostsAnomaliesSuccessResponsePayload = { + data: { + anomalies: [ + { + jobId: 'farequote_metric', + actual: 758.8220213274412, + anomalyScore: 0.024881740359975164, + duration: 900, + id: 'id1', + startTime: 1486845000000, + type: 'metrics_hosts', + partitionFieldName: 'airline', + partitionFieldValue: 'NKS', + typical: 545.7764658569108, + influencers: ['airline'], + }, + ], + hasMoreEntries: false, + paginationCursors: { + nextPageCursor: [1, 1], + previousPageCursor: [0, 0], + }, + }, +}; + +export const anomaliesHttpResponse = { + default: () => Promise.resolve({ ...anomalies }), +}; + +export type AnomaliesHttpMocks = keyof typeof anomaliesHttpResponse; diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/metadata.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/metadata.ts new file mode 100644 index 0000000000000..6f691ba78a65f --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/metadata.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { InfraMetadata } from '../../../../../../common/http_api'; + +export const HOST_ID = 'host-1'; +export const hostMetadata: InfraMetadata = { + id: HOST_ID, + name: HOST_ID, + info: { + agent: { + version: '8.5.0', + }, + host: { + hostname: 'Host 1', + ip: [ + '11.128.0.17', + 'test::4001:fff:test:11', + '169.254.123.1', + '11.22.33.44', + 'test::d8d1:123:frr4:ae6d', + '11.22.33.44', + 'test::8ce7:80ff:fe33:7a75', + '11.22.33.44', + 'test::800f:ebff:fecc:f658', + '11.22.33.44', + 'test::3333:asdf:fe1a:72e0', + '11.22.33.44', + 'test::c0c8:e8ff:fec5:1234', + '11.22.33.44', + 'test::ccbf:4fff:fe3a:6574', + '11.22.33.44', + 'test::2222:53ff:asdf:5sda', + '11.22.33.44', + 'test::cdb:14ff:asdf:5666', + '11.22.33.44', + 'test::11ba:3dff:asdf:d666', + '11.22.33.44', + 'test::ece8:eeee:2342:d334', + '11.22.33.44', + 'test::2402:d6ff:fe73:1234', + ], + os: { + family: 'debian', + name: 'Ubuntu', + platform: 'ubuntu', + version: '5.15.65+', + }, + }, + cloud: { + provider: 'gcp', + availability_zone: 'us-central1-c', + machine: { + type: 'n1-standard-4', + }, + }, + }, + features: [], +}; + +export const metadataHttpResponse = { + default: () => Promise.resolve({ ...hostMetadata }), + loading: () => new Promise(() => {}), + noData: () => Promise.resolve({ id: 'host-2', name: 'host-2', features: [] }), + error: () => + new Promise(() => { + throw new Error('err'); + }), +}; + +export type MetadataResponseMocks = keyof typeof metadataHttpResponse; diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/processes.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/processes.ts new file mode 100644 index 0000000000000..785182eb67e85 --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/processes.ts @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ProcessListAPIResponse } from '../../../../../../common/http_api'; + +const processes: ProcessListAPIResponse = { + processList: [ + { + cpu: 0.02466666666666667, + memory: 0.026166666666666668, + startTime: 1683624717239, + pid: 757, + state: 'running', + user: 'test_user', + command: '/Applications/Firefox.app/Contents/MacOS/firefox', + }, + { + cpu: 0.006833333333333334, + memory: 0.07200000000000001, + startTime: 1683624734638, + pid: 3524, + state: 'running', + user: 'test_user', + command: + '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) --ms-enable-electron-run-as-node --max-old-space-size=4096 /Users/test_user/projects/forks/kibana/node_modules/typescript/lib/tsserver.js --useInferredProjectPerProjectRoot --enableTelemetry --cancellationPipeName /var/folders/hq/pz_mbrf55lg_r37lr3l0n6nr0000gn/T/vscode-typescript501/b23862414d9a371466ef/tscancellation-9cbfb32954f6e79a5287.tmp* --locale en --noGetErrOnBackgroundUpdate --validateDefaultNpmLocation --useNodeIpc', + }, + { + cpu: 0.006666666666666667, + memory: 0.012000000000000002, + startTime: 1683633422827, + pid: 12355, + state: 'running', + user: 'test_user', + command: + '/Applications/Firefox.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container -childID 20 -isForBrowser -prefsLen 29966 -prefMapSize 241364 -jsInitLen 240056 -sbStartup -sbAppPath /Applications/Firefox.app -sbLevel 3 -sbAllowAudio -parentBuildID 20230424110519 -appDir /Applications/Firefox.app/Contents/Resources/browser -profile /Users/test_user/Library/Application Support/Firefox/Profiles/rqulcocl.default-release {c336b12a-302b-46a0-9c9d-d9f1a22b24b9} 757 gecko-crash-server-pipe.757 org.mozilla.machname.1351433086 tab', + }, + { + cpu: 0.0030000000000000005, + memory: 0.014, + startTime: 1683625026636, + pid: 6474, + state: 'running', + user: 'test_user', + command: + '/Users/test_user/.vscode/extensions/ambar.bundle-size-1.5.0/node_modules/esbuild-darwin-arm64/bin/esbuild --service=0.15.18 --ping', + }, + { + cpu: 0.0025, + memory: 0.016, + startTime: 1683624729210, + pid: 3034, + state: 'running', + user: 'test_user', + command: + '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Renderer).app/Contents/MacOS/Code Helper (Renderer) --type=renderer --user-data-dir=/Users/test_user/Library/Application Support/Code --standard-schemes=vscode-webview,vscode-file --secure-schemes=vscode-webview,vscode-file --bypasscsp-schemes --cors-schemes=vscode-webview,vscode-file --fetch-schemes=vscode-webview,vscode-file --service-worker-schemes=vscode-webview --streaming-schemes --app-path=/Applications/Visual Studio Code.app/Contents/Resources/app --no-sandbox --no-zygote --enable-blink-features=HighlightAPI --lang=en-GB --num-raster-threads=4 --enable-zero-copy --enable-gpu-memory-buffer-compositor-resources --enable-main-frame-before-activation --renderer-client-id=8 --launch-time-ticks=267710381 --shared-files --field-trial-handle=1718379636,r,13842708672762445701,9157690858550926405,131072 --disable-features=CalculateNativeWinOcclusion,SpareRendererForSitePerProcess --vscode-window-config=vscode:c40ae943-cf5f-4b4e-9ede-714d3202da26', + }, + { + cpu: 0.0013333333333333333, + memory: 0.011666666666666667, + startTime: 1683628721310, + pid: 11385, + state: 'running', + user: 'test_user', + command: + '/Applications/Slack.app/Contents/Frameworks/Slack Helper (Renderer).app/Contents/MacOS/Slack Helper (Renderer) --type=renderer --user-data-dir=/Users/test_user/Library/Application Support/Slack --standard-schemes=app,slack-webapp-dev --enable-sandbox --secure-schemes=app,slack-webapp-dev --bypasscsp-schemes=slack-webapp-dev --cors-schemes=slack-webapp-dev --fetch-schemes=slack-webapp-dev --service-worker-schemes=slack-webapp-dev --streaming-schemes --app-path=/Applications/Slack.app/Contents/Resources/app.asar --enable-sandbox --enable-blink-features=ExperimentalJSProfiler --disable-blink-features --first-renderer-process --autoplay-policy=no-user-gesture-required --enable-logging --force-color-profile=srgb --log-file=/Users/test_user/Library/Application Support/Slack/logs/default/electron_debug.log --lang=en-GB --num-raster-threads=4 --enable-zero-copy --enable-gpu-memory-buffer-compositor-resources --enable-main-frame-before-activation --renderer-client-id=4 --time-ticks-at-unix-epoch=-1683624461530404 --launch-time-ticks=4259772827 --shared-files --field-trial-handle=1718379636,r,7616643094726622586,3291986448361336128,131072 --disable-features=AllowAggressiveThrottlingWithWebSocket,CalculateNativeWinOcclusion,HardwareMediaKeyHandling,IntensiveWakeUpThrottling,LogJsConsoleMessages,RequestInitiatorSiteLockEnfocement,SpareRendererForSitePerProcess,WebRtcHideLocalIpsWithMdns,WinRetrieveSuggestionsOnlyOnDemand --window-type=main --seatbelt-client=71', + }, + { + cpu: 0.0013333333333333333, + memory: 0.0105, + startTime: 1683624737323, + pid: 3593, + state: 'running', + user: 'test_user', + command: + '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) --ms-enable-electron-run-as-node /Users/test_user/.vscode/extensions/streetsidesoftware.code-spell-checker-2.20.4/packages/_server/dist/main.js --node-ipc --clientProcessId=3508', + }, + { + cpu: 0.0011666666666666668, + memory: 0.014666666666666668, + startTime: 1683625569286, + pid: 8319, + state: 'running', + user: 'test_user', + command: + '/Applications/Firefox.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container -childID 14 -isForBrowser -prefsLen 29644 -prefMapSize 241364 -jsInitLen 240056 -sbStartup -sbAppPath /Applications/Firefox.app -sbLevel 3 -sbAllowAudio -parentBuildID 20230424110519 -appDir /Applications/Firefox.app/Contents/Resources/browser -profile /Users/test_user/Library/Application Support/Firefox/Profiles/rqulcocl.default-release {49cd6e6d-ed04-4355-8a7c-9a13fb9cbfa8} 757 gecko-crash-server-pipe.757 org.mozilla.machname.1880877485 tab', + }, + { + cpu: 0.001, + memory: 0.0030000000000000005, + startTime: 1683627994731, + pid: 10269, + state: 'running', + user: 'test_user', + command: './metricbeat -v -e -c metricbeat.dev.yml', + }, + { + cpu: 0.001, + memory: 0.006000000000000001, + startTime: 1683624717742, + pid: 784, + state: 'running', + user: 'test_user', + command: '/Applications/Visual Studio Code.app/Contents/MacOS/Electron', + }, + ], + summary: {}, +}; + +const summary: ProcessListAPIResponse['summary'] = { running: 366, total: 366 }; + +export const processesHttpResponse = { + default: () => Promise.resolve({ ...processes, summary }), + onlyProcesses: () => Promise.resolve({ ...processes, summary: {} }), + onlySummary: () => Promise.resolve({ summary, processList: [] }), + loading: () => new Promise(() => {}), + noData: () => Promise.resolve({ summary: {}, processList: [] }), + error: () => + new Promise(() => { + throw new Error('err'); + }), +}; + +export type ProcessesHttpMocks = keyof typeof processesHttpResponse; diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/http.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/http.ts new file mode 100644 index 0000000000000..ecff029a36149 --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/http.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 { HttpStart, HttpHandler } from '@kbn/core/public'; +import { Parameters } from '@storybook/react'; +import { INFA_ML_GET_METRICS_HOSTS_ANOMALIES_PATH } from '../../../../../common/http_api/infra_ml'; +import { metadataHttpResponse, type MetadataResponseMocks } from './fixtures/metadata'; +import { processesHttpResponse, type ProcessesHttpMocks } from './fixtures/processes'; +import { anomaliesHttpResponse, type AnomaliesHttpMocks } from './fixtures/anomalies'; + +export const getHttp = (params: Parameters): HttpStart => { + const http = { + basePath: { + prepend: (_path: string) => { + return ''; + }, + }, + + fetch: (async (path: string) => { + switch (path) { + case '/api/metrics/process_list': + return processesHttpResponse[params.mock as ProcessesHttpMocks](); + case '/api/infra/metadata': + return metadataHttpResponse[params.mock as MetadataResponseMocks](); + case INFA_ML_GET_METRICS_HOSTS_ANOMALIES_PATH: + return anomaliesHttpResponse[params.mock as AnomaliesHttpMocks](); + default: + return Promise.resolve({}); + } + }) as HttpHandler, + } as unknown as HttpStart; + + return http; +}; diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx b/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx new file mode 100644 index 0000000000000..fcb19ccf60b0b --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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, + type KibanaReactContextValue, +} from '@kbn/kibana-react-plugin/public'; +import { of } from 'rxjs'; +import { action } from '@storybook/addon-actions'; +import type { DecoratorFn } from '@storybook/react'; +import { useParameter } from '@storybook/addons'; +import { DeepPartial } from 'utility-types'; +import { LocatorPublic } from '@kbn/share-plugin/public'; +import type { PluginKibanaContextValue } from '../../../hooks/use_kibana'; +import { SourceProvider } from '../../../containers/metrics_source'; +import { getHttp } from './context/http'; +import { ProcessesHttpMocks } from './context/fixtures/processes'; +import { MetadataResponseMocks } from './context/fixtures/metadata'; + +export const DecorateWithKibanaContext: DecoratorFn = (story) => { + const initialProcesses = useParameter<{ mock: ProcessesHttpMocks | MetadataResponseMocks }>( + 'apiResponse', + { + mock: 'default', + } + )!; + + const mockServices: DeepPartial['services']> = { + application: { + currentAppId$: of('infra'), + navigateToUrl: async (url: string) => { + action(`Navigate to: ${url}`); + }, + getUrlForApp: (url: string) => url, + }, + data: { + query: { + filterManager: { + addFilters: () => action(`addFilters`), + removeFilter: () => action(`removeFilter`), + }, + }, + }, + notifications: { + toasts: { + add: () => { + action('toast'); + return { id: 'id' }; + }, + }, + }, + http: getHttp(initialProcesses), + share: { + url: { + locators: { + get: (_id: string) => + ({ + navigate: async () => + Promise.resolve(() => { + action( + 'https://kibana:8080/base-path/app/uptime/?search=host.name: "host1" OR host.ip: "192.168.0.1" OR monitor.ip: "192.168.0.1"' + ); + }), + } as unknown as LocatorPublic), + }, + }, + }, + }; + + return ( + + + {story()} + + + ); +}; diff --git a/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx b/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx index e5dcc75ce9c4e..cf2803b2182a8 100644 --- a/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx @@ -5,23 +5,51 @@ * 2.0. */ -import React from 'react'; -import { EuiButton, EuiCard } from '@elastic/eui'; -import { I18nProvider } from '@kbn/i18n-react'; +import React, { useEffect, useState } from 'react'; +import { EuiButton, EuiFlexGroup, EuiSwitch, type EuiSwitchEvent, EuiFlexItem } from '@elastic/eui'; import type { Meta, Story } from '@storybook/react/types-6-0'; import { i18n } from '@kbn/i18n'; -import { DecorateWithKibanaContext } from './asset_details.story_decorators'; +import { useArgs } from '@storybook/addons'; +import { DecoratorFn } from '@storybook/react'; import { AssetDetails } from './asset_details'; import { decorateWithGlobalStorybookThemeProviders } from '../../test_utils/use_global_storybook_theme'; import { FlyoutTabIds, type AssetDetailsProps } from './types'; +import { DecorateWithKibanaContext } from './__stories__/decorator'; -export default { - title: 'infra/Asset Details View/Asset Details Embeddable', +const links: AssetDetailsProps['links'] = ['apmServices', 'uptime']; + +const AssetDetailsDecorator: DecoratorFn = (story) => { + const [_, updateArgs] = useArgs(); + const [checked, setChecked] = React.useState(true); + + useEffect(() => { + if (checked) { + updateArgs({ links }); + } else { + updateArgs({ links: [] }); + } + }, [updateArgs, checked]); + + const handleChange = (e: EuiSwitchEvent) => { + setChecked(e.target.checked); + }; + + return ( + + + + + {story()} + + ); +}; + +const stories: Meta = { + title: 'infra/Asset Details View', decorators: [ - (wrappedStory) => {wrappedStory()}, - (wrappedStory) => {wrappedStory()}, decorateWithGlobalStorybookThemeProviders, DecorateWithKibanaContext, + AssetDetailsDecorator, ], component: AssetDetails, args: { @@ -41,13 +69,18 @@ export default { diskLatency: 0.15291777273162221, memoryTotal: 34359738368, }, + overrides: { + metadata: { + showActionsColumn: true, + }, + }, nodeType: 'host', currentTimeRange: { interval: '1s', from: 1683630468, to: 1683630469, }, - selectedTabId: 'metadata', + activeTabId: 'metadata', tabs: [ { id: FlyoutTabIds.METADATA, @@ -64,16 +97,17 @@ export default { 'data-test-subj': 'hostsView-flyout-tabs-processes', }, ], - links: ['apmServices', 'uptime'], - } as AssetDetailsProps, -} as Meta; -const Template: Story = (args) => { + links, + }, +}; + +const PageTemplate: Story = (args) => { return ; }; const FlyoutTemplate: Story = (args) => { - const [isOpen, setIsOpen] = React.useState(false); + const [isOpen, setIsOpen] = useState(false); const closeFlyout = () => setIsOpen(false); return (
@@ -90,60 +124,14 @@ const FlyoutTemplate: Story = (args) => { ); }; -export const DefaultAssetDetailsWithMetadataTabSelected = Template.bind({}); -DefaultAssetDetailsWithMetadataTabSelected.args = { - overrides: { - metadata: { - showActionsColumn: true, - }, - }, -}; - -export const AssetDetailsWithMetadataTabSelectedWithPersistedSearch = Template.bind({}); -AssetDetailsWithMetadataTabSelectedWithPersistedSearch.args = { - overrides: { - metadata: { - showActionsColumn: true, - query: 'ip', - }, - }, - activeTabId: 'metadata', - onTabsStateChange: () => {}, -}; - -export const AssetDetailsWithMetadataWithoutActions = Template.bind({}); -AssetDetailsWithMetadataWithoutActions.args = {}; +export const Page = PageTemplate.bind({}); -export const AssetDetailsWithMetadataWithoutLinks = Template.bind({}); -AssetDetailsWithMetadataWithoutLinks.args = { links: [] }; - -export const AssetDetailsAsFlyout = FlyoutTemplate.bind({}); -AssetDetailsAsFlyout.args = { +export const Flyout = FlyoutTemplate.bind({}); +Flyout.args = { renderMode: { showInFlyout: true, closeFlyout: () => {}, }, }; -export const AssetDetailsWithProcessesTabSelected = Template.bind({}); -AssetDetailsWithProcessesTabSelected.args = { - activeTabId: 'processes', - currentTimeRange: { - interval: '1s', - from: 1683630468, - to: 1683630469, - }, -}; - -export const AssetDetailsWithMetadataTabOnly = Template.bind({}); -AssetDetailsWithMetadataTabOnly.args = { - tabs: [ - { - id: FlyoutTabIds.METADATA, - name: i18n.translate('xpack.infra.metrics.nodeDetails.tabs.metadata', { - defaultMessage: 'Metadata', - }), - 'data-test-subj': 'hostsView-flyout-tabs-metadata', - }, - ], -}; +export default stories; diff --git a/x-pack/plugins/infra/public/components/asset_details/asset_details.story_decorators.tsx b/x-pack/plugins/infra/public/components/asset_details/asset_details.story_decorators.tsx deleted file mode 100644 index 7abc2d5937bef..0000000000000 --- a/x-pack/plugins/infra/public/components/asset_details/asset_details.story_decorators.tsx +++ /dev/null @@ -1,222 +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 { StoryContext } from '@storybook/react'; -import React from 'react'; -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { of } from 'rxjs'; -import { SourceProvider } from '../../containers/metrics_source'; - -export const DecorateWithKibanaContext = ( - wrappedStory: () => StoryFnReactReturnType, - _storyContext: StoryContext -) => { - const processesResponse = { - processList: [ - { - cpu: 0.02466666666666667, - memory: 0.026166666666666668, - startTime: 1683624717239, - pid: 757, - state: 'running', - user: 'test_user', - command: '/Applications/Firefox.app/Contents/MacOS/firefox', - }, - { - cpu: 0.006833333333333334, - memory: 0.07200000000000001, - startTime: 1683624734638, - pid: 3524, - state: 'running', - user: 'test_user', - command: - '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) --ms-enable-electron-run-as-node --max-old-space-size=4096 /Users/test_user/projects/forks/kibana/node_modules/typescript/lib/tsserver.js --useInferredProjectPerProjectRoot --enableTelemetry --cancellationPipeName /var/folders/hq/pz_mbrf55lg_r37lr3l0n6nr0000gn/T/vscode-typescript501/b23862414d9a371466ef/tscancellation-9cbfb32954f6e79a5287.tmp* --locale en --noGetErrOnBackgroundUpdate --validateDefaultNpmLocation --useNodeIpc', - }, - { - cpu: 0.006666666666666667, - memory: 0.012000000000000002, - startTime: 1683633422827, - pid: 12355, - state: 'running', - user: 'test_user', - command: - '/Applications/Firefox.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container -childID 20 -isForBrowser -prefsLen 29966 -prefMapSize 241364 -jsInitLen 240056 -sbStartup -sbAppPath /Applications/Firefox.app -sbLevel 3 -sbAllowAudio -parentBuildID 20230424110519 -appDir /Applications/Firefox.app/Contents/Resources/browser -profile /Users/test_user/Library/Application Support/Firefox/Profiles/rqulcocl.default-release {c336b12a-aaaa-aaaa-aaaa-d9f1a22b24b9} 757 gecko-crash-server-pipe.757 org.mozilla.machname.1351433086 tab', - }, - { - cpu: 0.0030000000000000005, - memory: 0.014, - startTime: 1683625026636, - pid: 6474, - state: 'running', - user: 'test_user', - command: - '/Users/test_user/.vscode/extensions/ambar.bundle-size-1.5.0/node_modules/esbuild-darwin-arm64/bin/esbuild --service=0.15.18 --ping', - }, - { - cpu: 0.0025, - memory: 0.016, - startTime: 1683624729210, - pid: 3034, - state: 'running', - user: 'test_user', - command: - '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Renderer).app/Contents/MacOS/Code Helper (Renderer) --type=renderer --user-data-dir=/Users/test_user/Library/Application Support/Code --standard-schemes=vscode-webview,vscode-file --secure-schemes=vscode-webview,vscode-file --bypasscsp-schemes --cors-schemes=vscode-webview,vscode-file --fetch-schemes=vscode-webview,vscode-file --service-worker-schemes=vscode-webview --streaming-schemes --app-path=/Applications/Visual Studio Code.app/Contents/Resources/app --no-sandbox --no-zygote --enable-blink-features=HighlightAPI --lang=en-GB --num-raster-threads=4 --enable-zero-copy --enable-gpu-memory-buffer-compositor-resources --enable-main-frame-before-activation --renderer-client-id=8 --launch-time-ticks=267710381 --shared-files --field-trial-handle=1718379636,r,13842708672762445701,9157690858550926405,131072 --disable-features=CalculateNativeWinOcclusion,SpareRendererForSitePerProcess --vscode-window-config=vscode:c40ae943-cf5f-4b4e-9ede-714d3202da26', - }, - { - cpu: 0.0013333333333333333, - memory: 0.011666666666666667, - startTime: 1683628721310, - pid: 11385, - state: 'running', - user: 'test_user', - command: - '/Applications/Slack.app/Contents/Frameworks/Slack Helper (Renderer).app/Contents/MacOS/Slack Helper (Renderer) --type=renderer --user-data-dir=/Users/test_user/Library/Application Support/Slack --standard-schemes=app,slack-webapp-dev --enable-sandbox --secure-schemes=app,slack-webapp-dev --bypasscsp-schemes=slack-webapp-dev --cors-schemes=slack-webapp-dev --fetch-schemes=slack-webapp-dev --service-worker-schemes=slack-webapp-dev --streaming-schemes --app-path=/Applications/Slack.app/Contents/Resources/app.asar --enable-sandbox --enable-blink-features=ExperimentalJSProfiler --disable-blink-features --first-renderer-process --autoplay-policy=no-user-gesture-required --enable-logging --force-color-profile=srgb --log-file=/Users/test_user/Library/Application Support/Slack/logs/default/electron_debug.log --lang=en-GB --num-raster-threads=4 --enable-zero-copy --enable-gpu-memory-buffer-compositor-resources --enable-main-frame-before-activation --renderer-client-id=4 --time-ticks-at-unix-epoch=-1683624461530404 --launch-time-ticks=4259772827 --shared-files --field-trial-handle=1718379636,r,7616643094726622586,3291986448361336128,131072 --disable-features=AllowAggressiveThrottlingWithWebSocket,CalculateNativeWinOcclusion,HardwareMediaKeyHandling,IntensiveWakeUpThrottling,LogJsConsoleMessages,RequestInitiatorSiteLockEnfocement,SpareRendererForSitePerProcess,WebRtcHideLocalIpsWithMdns,WinRetrieveSuggestionsOnlyOnDemand --window-type=main --seatbelt-client=71', - }, - { - cpu: 0.0013333333333333333, - memory: 0.0105, - startTime: 1683624737323, - pid: 3593, - state: 'running', - user: 'test_user', - command: - '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) --ms-enable-electron-run-as-node /Users/test_user/.vscode/extensions/streetsidesoftware.code-spell-checker-2.20.4/packages/_server/dist/main.js --node-ipc --clientProcessId=3508', - }, - { - cpu: 0.0011666666666666668, - memory: 0.014666666666666668, - startTime: 1683625569286, - pid: 8319, - state: 'running', - user: 'test_user', - command: - '/Applications/Firefox.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container -childID 14 -isForBrowser -prefsLen 29644 -prefMapSize 241364 -jsInitLen 240056 -sbStartup -sbAppPath /Applications/Firefox.app -sbLevel 3 -sbAllowAudio -parentBuildID 20230424110519 -appDir /Applications/Firefox.app/Contents/Resources/browser -profile /Users/test_user/Library/Application Support/Firefox/Profiles/rqulcocl.default-release {49cd6e6d-ed04-4355-8a7c-9a13fb9cbfa8} 757 gecko-crash-server-pipe.757 org.mozilla.machname.1880877485 tab', - }, - { - cpu: 0.001, - memory: 0.0030000000000000005, - startTime: 1683627994731, - pid: 10269, - state: 'running', - user: 'test_user', - command: './metricbeat -v -e -c metricbeat.dev.yml', - }, - { - cpu: 0.001, - memory: 0.006000000000000001, - startTime: 1683624717742, - pid: 784, - state: 'running', - user: 'test_user', - command: '/Applications/Visual Studio Code.app/Contents/MacOS/Electron', - }, - ], - summary: { running: 366, total: 366 }, - }; - - const metadataResponse = { - id: 'host1', - name: 'host1', - info: { - cloud: { - availability_zone: 'us-central1-c', - instance: { - name: 'host2', - id: '1234567891234567896', - }, - provider: 'gcp', - service: { - name: 'GCE', - }, - machine: { - type: 'e2-machine', - }, - project: { - id: 'some-project', - }, - account: { - id: 'some-project', - }, - }, - agent: { - name: 'host2', - id: '1a3s3f5g-2222-aaaa-1d35-fd34133t241', - ephemeral_id: 'fdaf43q5-rwe3-ee22-6666-fdsfhwy34535', - type: 'metricbeat', - version: '8.8.0', - }, - host: { - hostname: 'host2', - os: { - build: '1111.1111', - kernel: '10.0.1111.1111 (WinBuild.160101.0800)', - name: 'Windows Server 2019 Datacenter', - family: 'windows', - type: 'windows', - version: '10.0', - platform: 'windows', - }, - ip: ['as98::111r:aab2s:w123:v00s', '192.168.0.25'], - name: 'host2', - id: '1245t34f-aaaa-6666-1111-5555666777722', - mac: ['66-66-0A-66-00-66'], - architecture: 'x86_64', - }, - }, - features: [], - }; - - const mockServices = { - application: { - currentAppId$: of('infra'), - navigateToUrl: () => {}, - }, - dataViews: { create: () => {} }, - data: { - query: { - filterManager: { filterManagerService: { addFilters: () => {}, removeFilter: () => {} } }, - }, - }, - notifications: { toasts: { add: () => {}, toastsService: { addSuccess: () => {} } } }, - telemetry: () => {}, - http: { - basePath: { - prepend: (_: string) => '', - }, - patch: () => {}, - fetch: async (path: string) => { - switch (path) { - case '/api/infra/metadata': - return metadataResponse; - case '/api/metrics/process_list': - return { ...processesResponse, loading: false }; - default: - return {}; - } - }, - }, - share: { - url: { - locators: { - get: () => ({ - navigate: () => - `https://kibana:8080/base-path/app/uptime/?search=host.name: "host1" OR host.ip: "192.168.0.1" OR monitor.ip: "192.168.0.1"`, - }), - }, - }, - }, - }; - - return ( - - - {wrappedStory()} - - - ); -}; diff --git a/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.stories.tsx b/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.stories.tsx index fb8f8a4a7a053..7e5e973f83f78 100644 --- a/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.stories.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.stories.tsx @@ -5,45 +5,22 @@ * 2.0. */ -import { EuiCard } from '@elastic/eui'; -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import type { Meta, Story } from '@storybook/react/types-6-0'; import React from 'react'; -import { of } from 'rxjs'; + import { decorateWithGlobalStorybookThemeProviders } from '../../../test_utils/use_global_storybook_theme'; +import { DecorateWithKibanaContext } from '../__stories__/decorator'; import { LinkToApmServices, type LinkToApmServicesProps } from './link_to_apm_services'; -const mockServices = { - application: { - currentAppId$: of('infra'), - navigateToUrl: () => {}, - }, - http: { - basePath: { - prepend: (_: string) => '', - }, - patch: () => {}, - }, -}; - -export default { +const stories: Meta = { title: 'infra/Asset Details View/Components/Links', - decorators: [ - (wrappedStory) => {wrappedStory()}, - (wrappedStory) => ( - - {wrappedStory()} - - ), - decorateWithGlobalStorybookThemeProviders, - ], + decorators: [decorateWithGlobalStorybookThemeProviders, DecorateWithKibanaContext], component: LinkToApmServices, args: { hostName: 'host1', apmField: 'host.hostname', }, -} as Meta; +}; const TemplateApm: Story = (args) => { return ; @@ -54,3 +31,5 @@ ApmServicesLink.args = { apmField: 'services', hostName: 'host1', }; + +export default stories; diff --git a/x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.stories.tsx b/x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.stories.tsx index b4f0ca2011dc3..f5620533a7b49 100644 --- a/x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.stories.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.stories.tsx @@ -5,38 +5,15 @@ * 2.0. */ -import { EuiCard } from '@elastic/eui'; -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import type { Meta, Story } from '@storybook/react/types-6-0'; import React from 'react'; import { decorateWithGlobalStorybookThemeProviders } from '../../../test_utils/use_global_storybook_theme'; +import { DecorateWithKibanaContext } from '../__stories__/decorator'; import { LinkToUptime, type LinkToUptimeProps } from './link_to_uptime'; -const mockServices = { - share: { - url: { - locators: { - get: () => ({ - navigate: () => - `https://kibana:8080/base-path/app/uptime/?search=host.name: "host1" OR host.ip: "192.168.0.1" OR monitor.ip: "192.168.0.1"`, - }), - }, - }, - }, -}; - -export default { +const stories: Meta = { title: 'infra/Asset Details View/Components/Links', - decorators: [ - (wrappedStory) => {wrappedStory()}, - (wrappedStory) => ( - - {wrappedStory()} - - ), - decorateWithGlobalStorybookThemeProviders, - ], + decorators: [decorateWithGlobalStorybookThemeProviders, DecorateWithKibanaContext], component: LinkToUptime, args: { nodeType: 'host', @@ -57,11 +34,12 @@ export default { memoryTotal: 34359738368, }, }, -} as Meta; +}; const TemplateUptime: Story = (args) => { return ; }; export const UptimeLink = TemplateUptime.bind({}); -UptimeLink.args = {}; + +export default stories; diff --git a/x-pack/plugins/infra/public/components/asset_details/tab_content/tab_content.tsx b/x-pack/plugins/infra/public/components/asset_details/tab_content/tab_content.tsx index 506306760bc85..bcfe19b338903 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tab_content/tab_content.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tab_content/tab_content.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { useTabSwitcherContext } from '../hooks/use_tab_switcher'; -import Metadata from '../tabs/metadata/metadata'; +import { Metadata } from '../tabs/metadata/metadata'; import { Processes } from '../tabs/processes/processes'; import { FlyoutTabIds, type TabState, type AssetDetailsProps } from '../types'; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.stories.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.stories.tsx new file mode 100644 index 0000000000000..a63d123919580 --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.stories.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 type { Meta, Story } from '@storybook/react/types-6-0'; +import React from 'react'; +import { decorateWithGlobalStorybookThemeProviders } from '../../../../test_utils/use_global_storybook_theme'; +import { Metadata, MetadataProps } from './metadata'; +import { DecorateWithKibanaContext } from '../../__stories__/decorator'; + +const stories: Meta = { + title: 'infra/Asset Details View/Components/Metadata', + decorators: [decorateWithGlobalStorybookThemeProviders, DecorateWithKibanaContext], + component: Metadata, + args: { + currentTimeRange: { + from: 1679316685686, + to: 1679585836087, + interval: '1m', + }, + nodeType: 'host', + node: { + id: 'host-1', + name: 'host-1', + ip: '192.168.0.1', + os: 'iOS', + title: { + name: 'host-1', + cloudProvider: 'gcp', + }, + rx: 0, + tx: 0, + memory: 0.5445920331099282, + cpu: 0.2000718443867342, + diskLatency: 0, + memoryTotal: 16777216, + }, + showActionsColumn: false, + }, +}; + +const Template: Story = (args) => { + return ; +}; + +export const Default = Template.bind({}); + +export const WithActions = Template.bind({}); +WithActions.args = { + showActionsColumn: true, +}; + +export const NoData = Template.bind({}); +NoData.parameters = { + apiResponse: { + mock: 'noData', + }, +}; + +export const LoadingState = Template.bind({}); +LoadingState.parameters = { + apiResponse: { + mock: 'loading', + }, +}; + +export const ErrorState = Template.bind({}); +ErrorState.parameters = { + apiResponse: { + mock: 'error', + }, +}; + +export default stories; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.stories.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.stories.tsx deleted file mode 100644 index 48c17b35c70fe..0000000000000 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.stories.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiCard } from '@elastic/eui'; -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import type { Meta, Story } from '@storybook/react/types-6-0'; -import React from 'react'; -import { decorateWithGlobalStorybookThemeProviders } from '../../../../test_utils/use_global_storybook_theme'; -import { Table, Props } from './table'; - -const mockServices = { - data: { - query: { - filterManager: { filterManagerService: { addFilters: () => {}, removeFilter: () => {} } }, - }, - }, - notifications: { toasts: { toastsService: { addSuccess: () => {} } } }, - telemetry: () => {}, -}; - -export default { - title: 'infra/Asset Details View/Components/Metadata Table', - decorators: [ - (wrappedStory) => {wrappedStory()}, - (wrappedStory) => ( - - {wrappedStory()} - - ), - decorateWithGlobalStorybookThemeProviders, - ], - component: Table, - args: { - rows: [ - { name: 'host.hostname', value: 'host 1' }, - { - name: 'host.ip', - value: [ - '192.168.0.1', - '192.168.0.2', - '192.168.0.3', - '192.168.0.4', - '192.168.0.5', - '192.168.0.6', - '192.168.0.7', - '192.168.0.8', - '192.168.0.9', - '192.168.0.10', - ], - }, - { name: 'host.os.name', value: 'macOs' }, - { name: 'host.os.family', value: 'darwin' }, - { name: 'host.os.platform', value: 'darwin' }, - { name: 'host.os.version', value: '13.3.1' }, - { name: 'agent.version', value: '8.5.0' }, - ], - loading: false, - }, -} as Meta; - -const Template: Story = (args) => { - return ; -}; - -export const BasicData = Template.bind({}); -BasicData.args = {}; - -export const CloudData = Template.bind({}); -CloudData.args = { - rows: [ - { name: 'host.hostname', value: 'host 2' }, - { - name: 'host.ip', - value: [ - '11.128.0.17', - 'test::4001:fff:test:11', - '169.254.123.1', - '11.22.33.44', - 'test::d8d1:123:frr4:ae6d', - '11.22.33.44', - 'test::8ce7:80ff:fe33:7a75', - '11.22.33.44', - 'test::800f:ebff:fecc:f658', - '11.22.33.44', - 'test::3333:asdf:fe1a:72e0', - '11.22.33.44', - 'test::c0c8:e8ff:fec5:1234', - '11.22.33.44', - 'test::ccbf:4fff:fe3a:6574', - '11.22.33.44', - 'test::2222:53ff:asdf:5sda', - '11.22.33.44', - 'test::cdb:14ff:asdf:5666', - '11.22.33.44', - 'test::11ba:3dff:asdf:d666', - '11.22.33.44', - 'test::ece8:eeee:2342:d334', - '11.22.33.44', - 'test::2402:d6ff:fe73:1234', - ], - }, - { name: 'host.os.name', value: 'Ubuntu' }, - { name: 'host.os.family', value: 'debian' }, - { name: 'host.os.platform', value: 'ubuntu' }, - { name: 'host.os.version', value: '5.15.65+' }, - { name: 'cloud.availability_zone', value: 'us-central1-c' }, - { name: 'cloud.machine.type', value: 'n1-standard-4' }, - { name: 'cloud.provider', value: 'gcp' }, - { name: 'agent.version', value: '8.9.0' }, - ], - loading: false, -}; - -export const Loading = Template.bind({}); -Loading.args = { - loading: true, - rows: [], -}; - -export const NoMetadata = Template.bind({}); -NoMetadata.args = { - loading: false, - rows: [], -}; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.tsx index 6be4445c83d28..b918e50781778 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/table.tsx @@ -202,7 +202,7 @@ const ExpandableContent = (props: ExpandableContentProps) => { )} - {isExpanded && others.map((item) => {item})} + {isExpanded && others.map((item, index) => {item})} {hasOthers && isExpanded && ( diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.stories.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.stories.tsx index 09b4d30147c17..47d7beff4c1d1 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.stories.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.stories.tsx @@ -5,23 +5,15 @@ * 2.0. */ -import { EuiCard } from '@elastic/eui'; -import { I18nProvider } from '@kbn/i18n-react'; -import type { Meta, Story } from '@storybook/react/types-6-0'; import React from 'react'; -import { DecorateWithKibanaContext } from './processes.story_decorators'; - +import type { Meta, Story } from '@storybook/react/types-6-0'; +import { DecorateWithKibanaContext } from '../../__stories__/decorator'; import { Processes, type ProcessesProps } from './processes'; import { decorateWithGlobalStorybookThemeProviders } from '../../../../test_utils/use_global_storybook_theme'; -export default { +const stories: Meta = { title: 'infra/Asset Details View/Components/Processes', - decorators: [ - (wrappedStory) => {wrappedStory()}, - (wrappedStory) => {wrappedStory()}, - decorateWithGlobalStorybookThemeProviders, - DecorateWithKibanaContext, - ], + decorators: [decorateWithGlobalStorybookThemeProviders, DecorateWithKibanaContext], component: Processes, args: { node: { @@ -43,39 +35,48 @@ export default { nodeType: 'host', currentTime: 1683630468, }, -} as Meta; +}; const Template: Story = (args) => { return ; }; -export const DefaultProcessesAndSummary = Template.bind({}); -DefaultProcessesAndSummary.args = {}; - -export const Loading = Template.bind({}); -Loading.parameters = { - show: { - contentType: 'loading', - }, -}; +export const Default = Template.bind({}); +Default.args = {}; export const OnlySummary = Template.bind({}); OnlySummary.parameters = { - show: { - contentType: 'onlySummary', + apiResponse: { + mock: 'onlySummary', }, }; export const OnlyProcesses = Template.bind({}); OnlyProcesses.parameters = { - show: { - contentType: 'onlyProcesses', + apiResponse: { + mock: 'onlyProcesses', }, }; export const NoData = Template.bind({}); NoData.parameters = { - show: { - contentType: 'noData', + apiResponse: { + mock: 'noData', }, }; + +export const LoadingState = Template.bind({}); +LoadingState.parameters = { + apiResponse: { + mock: 'loading', + }, +}; + +export const ErrorState = Template.bind({}); +ErrorState.parameters = { + apiResponse: { + mock: 'error', + }, +}; + +export default stories; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.story_decorators.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.story_decorators.tsx deleted file mode 100644 index 4310467a51aec..0000000000000 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.story_decorators.tsx +++ /dev/null @@ -1,161 +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 { StoryContext } from '@storybook/react'; -import React from 'react'; -// This should be fixed when the component is moved as embeddable -// eslint-disable-next-line import/no-extraneous-dependencies -import { useParameter } from '@storybook/addons'; -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { SourceProvider } from '../../../../containers/metrics_source'; - -export const DecorateWithKibanaContext = ( - wrappedStory: () => StoryFnReactReturnType, - _storyContext: StoryContext -) => { - const processes = { - processList: [ - { - cpu: 0.02466666666666667, - memory: 0.026166666666666668, - startTime: 1683624717239, - pid: 757, - state: 'running', - user: 'test_user', - command: '/Applications/Firefox.app/Contents/MacOS/firefox', - }, - { - cpu: 0.006833333333333334, - memory: 0.07200000000000001, - startTime: 1683624734638, - pid: 3524, - state: 'running', - user: 'test_user', - command: - '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) --ms-enable-electron-run-as-node --max-old-space-size=4096 /Users/test_user/projects/forks/kibana/node_modules/typescript/lib/tsserver.js --useInferredProjectPerProjectRoot --enableTelemetry --cancellationPipeName /var/folders/hq/pz_mbrf55lg_r37lr3l0n6nr0000gn/T/vscode-typescript501/b23862414d9a371466ef/tscancellation-9cbfb32954f6e79a5287.tmp* --locale en --noGetErrOnBackgroundUpdate --validateDefaultNpmLocation --useNodeIpc', - }, - { - cpu: 0.006666666666666667, - memory: 0.012000000000000002, - startTime: 1683633422827, - pid: 12355, - state: 'running', - user: 'test_user', - command: - '/Applications/Firefox.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container -childID 20 -isForBrowser -prefsLen 29966 -prefMapSize 241364 -jsInitLen 240056 -sbStartup -sbAppPath /Applications/Firefox.app -sbLevel 3 -sbAllowAudio -parentBuildID 20230424110519 -appDir /Applications/Firefox.app/Contents/Resources/browser -profile /Users/test_user/Library/Application Support/Firefox/Profiles/rqulcocl.default-release {c336b12a-302b-46a0-9c9d-d9f1a22b24b9} 757 gecko-crash-server-pipe.757 org.mozilla.machname.1351433086 tab', - }, - { - cpu: 0.0030000000000000005, - memory: 0.014, - startTime: 1683625026636, - pid: 6474, - state: 'running', - user: 'test_user', - command: - '/Users/test_user/.vscode/extensions/ambar.bundle-size-1.5.0/node_modules/esbuild-darwin-arm64/bin/esbuild --service=0.15.18 --ping', - }, - { - cpu: 0.0025, - memory: 0.016, - startTime: 1683624729210, - pid: 3034, - state: 'running', - user: 'test_user', - command: - '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Renderer).app/Contents/MacOS/Code Helper (Renderer) --type=renderer --user-data-dir=/Users/test_user/Library/Application Support/Code --standard-schemes=vscode-webview,vscode-file --secure-schemes=vscode-webview,vscode-file --bypasscsp-schemes --cors-schemes=vscode-webview,vscode-file --fetch-schemes=vscode-webview,vscode-file --service-worker-schemes=vscode-webview --streaming-schemes --app-path=/Applications/Visual Studio Code.app/Contents/Resources/app --no-sandbox --no-zygote --enable-blink-features=HighlightAPI --lang=en-GB --num-raster-threads=4 --enable-zero-copy --enable-gpu-memory-buffer-compositor-resources --enable-main-frame-before-activation --renderer-client-id=8 --launch-time-ticks=267710381 --shared-files --field-trial-handle=1718379636,r,13842708672762445701,9157690858550926405,131072 --disable-features=CalculateNativeWinOcclusion,SpareRendererForSitePerProcess --vscode-window-config=vscode:c40ae943-cf5f-4b4e-9ede-714d3202da26', - }, - { - cpu: 0.0013333333333333333, - memory: 0.011666666666666667, - startTime: 1683628721310, - pid: 11385, - state: 'running', - user: 'test_user', - command: - '/Applications/Slack.app/Contents/Frameworks/Slack Helper (Renderer).app/Contents/MacOS/Slack Helper (Renderer) --type=renderer --user-data-dir=/Users/test_user/Library/Application Support/Slack --standard-schemes=app,slack-webapp-dev --enable-sandbox --secure-schemes=app,slack-webapp-dev --bypasscsp-schemes=slack-webapp-dev --cors-schemes=slack-webapp-dev --fetch-schemes=slack-webapp-dev --service-worker-schemes=slack-webapp-dev --streaming-schemes --app-path=/Applications/Slack.app/Contents/Resources/app.asar --enable-sandbox --enable-blink-features=ExperimentalJSProfiler --disable-blink-features --first-renderer-process --autoplay-policy=no-user-gesture-required --enable-logging --force-color-profile=srgb --log-file=/Users/test_user/Library/Application Support/Slack/logs/default/electron_debug.log --lang=en-GB --num-raster-threads=4 --enable-zero-copy --enable-gpu-memory-buffer-compositor-resources --enable-main-frame-before-activation --renderer-client-id=4 --time-ticks-at-unix-epoch=-1683624461530404 --launch-time-ticks=4259772827 --shared-files --field-trial-handle=1718379636,r,7616643094726622586,3291986448361336128,131072 --disable-features=AllowAggressiveThrottlingWithWebSocket,CalculateNativeWinOcclusion,HardwareMediaKeyHandling,IntensiveWakeUpThrottling,LogJsConsoleMessages,RequestInitiatorSiteLockEnfocement,SpareRendererForSitePerProcess,WebRtcHideLocalIpsWithMdns,WinRetrieveSuggestionsOnlyOnDemand --window-type=main --seatbelt-client=71', - }, - { - cpu: 0.0013333333333333333, - memory: 0.0105, - startTime: 1683624737323, - pid: 3593, - state: 'running', - user: 'test_user', - command: - '/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) --ms-enable-electron-run-as-node /Users/test_user/.vscode/extensions/streetsidesoftware.code-spell-checker-2.20.4/packages/_server/dist/main.js --node-ipc --clientProcessId=3508', - }, - { - cpu: 0.0011666666666666668, - memory: 0.014666666666666668, - startTime: 1683625569286, - pid: 8319, - state: 'running', - user: 'test_user', - command: - '/Applications/Firefox.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container -childID 14 -isForBrowser -prefsLen 29644 -prefMapSize 241364 -jsInitLen 240056 -sbStartup -sbAppPath /Applications/Firefox.app -sbLevel 3 -sbAllowAudio -parentBuildID 20230424110519 -appDir /Applications/Firefox.app/Contents/Resources/browser -profile /Users/test_user/Library/Application Support/Firefox/Profiles/rqulcocl.default-release {49cd6e6d-ed04-4355-8a7c-9a13fb9cbfa8} 757 gecko-crash-server-pipe.757 org.mozilla.machname.1880877485 tab', - }, - { - cpu: 0.001, - memory: 0.0030000000000000005, - startTime: 1683627994731, - pid: 10269, - state: 'running', - user: 'test_user', - command: './metricbeat -v -e -c metricbeat.dev.yml', - }, - { - cpu: 0.001, - memory: 0.006000000000000001, - startTime: 1683624717742, - pid: 784, - state: 'running', - user: 'test_user', - command: '/Applications/Visual Studio Code.app/Contents/MacOS/Electron', - }, - ], - }; - - const summary = { summary: { running: 366, total: 366 } }; - - const contentTypes = { - processesAndSummary: { ...processes, ...summary, loading: false }, - onlyProcesses: { ...processes, summary: {}, loading: false }, - onlySummary: { ...summary, processList: [] }, - loading: { loading: true }, - noData: { loading: false, summary: {}, processList: [] }, - }; - - const initialProcesses = useParameter<{ contentType: keyof typeof contentTypes }>('show', { - contentType: 'processesAndSummary', - })!; - - const mockServices = { - http: { - basePath: { - prepend: (_: string) => '', - }, - patch: () => {}, - fetch: async (path: string) => { - switch (path) { - case '/api/metrics/process_list': - return contentTypes[initialProcesses?.contentType]; - default: - return {}; - } - }, - }, - }; - - return ( - - - {wrappedStory()} - - - ); -}; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.tsx index cb6660c64a926..6da77bd7d0720 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/processes/processes.tsx @@ -21,7 +21,6 @@ import { parseSearchString } from './parse_search_string'; import { ProcessesTable } from './processes_table'; import { STATE_NAMES } from './states'; import { SummaryTable } from './summary_table'; -import { TabContent } from '../../../../pages/metrics/inventory_view/components/node_details/tabs/shared'; import { SortBy, useProcessList, @@ -99,93 +98,88 @@ export const Processes = ({ }, [onSearchFilterChange]); return ( - - - + + + +

+ {i18n.translate('xpack.infra.metrics.nodeDetails.processesHeader', { + defaultMessage: 'Top processes', + })}{' '} + +

+
+ + + + {!error ? ( + - - -

- {i18n.translate('xpack.infra.metrics.nodeDetails.processesHeader', { - defaultMessage: 'Top processes', - })}{' '} - -

-
- - + {i18n.translate('xpack.infra.metrics.nodeDetails.processListError', { + defaultMessage: 'Unable to load process data', + })} + + } + actions={ + + {i18n.translate('xpack.infra.metrics.nodeDetails.processListRetry', { + defaultMessage: 'Try again', + })} + + } /> - - {!error ? ( - - ) : ( - - {i18n.translate('xpack.infra.metrics.nodeDetails.processListError', { - defaultMessage: 'Unable to load process data', - })} - - } - actions={ - - {i18n.translate('xpack.infra.metrics.nodeDetails.processListRetry', { - defaultMessage: 'Try again', - })} - - } - /> - )} -
-
+ )} + ); }; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_process_list.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_process_list.ts index a3aebd8d39bf7..532195ba32cc0 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_process_list.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_process_list.ts @@ -9,7 +9,7 @@ import createContainter from 'constate'; import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import { ProcessListAPIResponse, ProcessListAPIResponseRT } from '../../../../../common/http_api'; import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; import { useHTTPRequest } from '../../../../hooks/use_http_request'; @@ -29,7 +29,6 @@ export function useProcessList( const { createDerivedIndexPattern } = useSourceContext(); const indexPattern = createDerivedIndexPattern().title; - const [inErrorState, setInErrorState] = useState(false); const decodeResponse = (response: any) => { return pipe( ProcessListAPIResponseRT.decode(response), @@ -58,15 +57,12 @@ export function useProcessList( decodeResponse ); - useEffect(() => setInErrorState(true), [error]); - useEffect(() => setInErrorState(false), [loading]); - useEffect(() => { makeRequest(); }, [makeRequest]); return { - error: inErrorState, + error: (error && error.message) || null, loading, response, makeRequest, From aa1d266939658d6793b3d197b574fabcebca6fe1 Mon Sep 17 00:00:00 2001 From: Trevor Pierce <1Copenut@users.noreply.github.com> Date: Wed, 31 May 2023 13:51:10 -0500 Subject: [PATCH 02/31] Upgrade EUI to v81.0.0 (#158330) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary `@elastic/eui@80.0.0` ⏩ `@elastic/eui@81.0.0` --- ## [`81.0.0`](https://github.com/elastic/eui/tree/v81.0.0) - Added ability to set `options.checked` to "mixed" in `EuiSelectable` ([#6774](https://github.com/elastic/eui/pull/6774)) **Bug fixes** - Portalled components (e.g. `EuiPopover`, `EuiModal`, `EuiFlyout`) will correctly inherit text color from its nearest `EuiThemeProvider` parent. `` is no longer needed. ([#6775](https://github.com/elastic/eui/pull/6775)) **Breaking changes** - `EuiSelectable` no longer renders a `data-test-selected` attribute on its list items. Use the `aria-checked` property instead ([#6774](https://github.com/elastic/eui/pull/6774)) - Nested `EuiThemeProvider`s now render a wrapping `` element in order to correctly set the inherited text `color` of all descendants. `` is no longer needed. ([#6775](https://github.com/elastic/eui/pull/6775)) --------- Co-authored-by: Stratoula Kalafateli Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Constance Chen --- package.json | 2 +- .../table_list/src/table_list_view.test.tsx | 6 +-- .../__snapshots__/i18n_service.test.tsx.snap | 12 +++-- .../src/i18n_eui_mapping.tsx | 46 +++++++++++-------- src/dev/license_checker/config.ts | 2 +- .../components/options_list_popover.test.tsx | 14 +++--- .../components/footer/page_controls.tsx | 8 ++-- .../form_based/layerpanel.test.tsx | 2 +- .../e2e/detection_rules/bulk_edit_rules.cy.ts | 15 +++--- .../cypress/screens/alerts_detection_rules.ts | 2 +- .../cypress/tasks/rules_bulk_edit.ts | 5 +- .../effected_policy_select/test_utils.ts | 2 +- .../response_actions_log.test.tsx | 16 +++---- .../components/policy_form_layout.tsx | 23 ++++------ .../view/response_actions_list_page.test.tsx | 18 +++++--- .../overview_panels/integrations_panel.tsx | 6 +-- .../translations/translations/fr-FR.json | 5 -- .../translations/translations/ja-JP.json | 5 -- .../translations/translations/zh-CN.json | 5 -- .../services/ml/stack_management_jobs.ts | 2 +- yarn.lock | 20 ++++---- 21 files changed, 109 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index 8faa96541c13d..2a5a779f182b1 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.8.0-canary.2", "@elastic/ems-client": "8.4.0", - "@elastic/eui": "80.0.0", + "@elastic/eui": "81.0.0", "@elastic/filesaver": "1.1.2", "@elastic/node-crypto": "1.2.1", "@elastic/numeral": "^2.5.1", diff --git a/packages/content-management/table_list/src/table_list_view.test.tsx b/packages/content-management/table_list/src/table_list_view.test.tsx index 0245af450fb8a..6b0b850cddcd4 100644 --- a/packages/content-management/table_list/src/table_list_view.test.tsx +++ b/packages/content-management/table_list/src/table_list_view.test.tsx @@ -450,7 +450,7 @@ describe('TableListView', () => { expect(filterOptions.map((wrapper) => wrapper.text())).toEqual([ 'Name A-Z ', 'Name Z-A ', - 'Recently updated - Checked option. ', + 'Recently updated. Checked option. ', 'Least recently updated ', ]); }); @@ -532,7 +532,7 @@ describe('TableListView', () => { expect(filterOptions.map((wrapper) => wrapper.text())).toEqual([ 'Name A-Z ', 'Name Z-A ', - 'Recently updated - Checked option. ', // checked + 'Recently updated. Checked option. ', // checked 'Least recently updated ', ]); @@ -571,7 +571,7 @@ describe('TableListView', () => { expect(filterOptions.map((wrapper) => wrapper.text())).toEqual([ 'Name A-Z ', - 'Name Z-A - Checked option. ', // now this option is checked + 'Name Z-A. Checked option. ', // now this option is checked 'Recently updated ', 'Least recently updated ', ]); diff --git a/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap b/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap index 50c6cdba510ba..4506a65aa6e19 100644 --- a/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap +++ b/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap @@ -294,13 +294,15 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiSelectable.placeholderName": "Filter options", "euiSelectable.screenReaderInstructions": "Use the Up and Down arrow keys to move focus over options. Press Enter to select. Press Escape to collapse options.", "euiSelectable.searchResults": [Function], + "euiSelectableListItem.checkOptionInstructions": "To check this option, press Enter.", "euiSelectableListItem.checkedOption": "Checked option.", - "euiSelectableListItem.checkedOptionInstructions": "To uncheck this option, press enter.", + "euiSelectableListItem.excludeOptionInstructions": "To exclude this option, press Enter.", "euiSelectableListItem.excludedOption": "Excluded option.", - "euiSelectableListItem.excludedOptionInstructions": "To uncheck this option, press enter.", - "euiSelectableListItem.includedOption": "Selected option.", - "euiSelectableListItem.includedOptionInstructions": "To exclude this option, press enter.", - "euiSelectableListItem.unckeckedOptionInstructions": "To select this option, press enter.", + "euiSelectableListItem.mixedOption": "Mixed (indeterminate) option.", + "euiSelectableListItem.mixedOptionExcludeInstructions": "To exclude this option for all, press Enter twice.", + "euiSelectableListItem.mixedOptionInstructions": "To check this option for all, press Enter once.", + "euiSelectableListItem.mixedOptionUncheckInstructions": "To uncheck this option for all, press Enter twice.", + "euiSelectableListItem.uncheckOptionInstructions": "To uncheck this option, press Enter.", "euiSelectableTemplateSitewide.loadingResults": "Loading results", "euiSelectableTemplateSitewide.noResults": "No results available", "euiSelectableTemplateSitewide.onFocusBadgeGoTo": "Go to", diff --git a/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx b/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx index 642e444f038ce..c614bf698bd19 100644 --- a/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx +++ b/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx @@ -1499,40 +1499,50 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: 'Checked option.', } ), - 'euiSelectableListItem.checkedOptionInstructions': i18n.translate( - 'core.euiSelectableListItem.checkedOptionInstructions', + 'euiSelectableListItem.excludedOption': i18n.translate( + 'core.euiSelectableListItem.excludedOption', { - defaultMessage: 'To uncheck this option, press enter.', + defaultMessage: 'Excluded option.', } ), - 'euiSelectableListItem.includedOption': i18n.translate( - 'core.euiSelectableListItem.includedOption', + 'euiSelectableListItem.checkOptionInstructions': i18n.translate( + 'core.euiSelectableListItem.checkOptionInstructions', { - defaultMessage: 'Selected option.', + defaultMessage: 'To check this option, press Enter.', } ), - 'euiSelectableListItem.includedOptionInstructions': i18n.translate( - 'core.euiSelectableListItem.includedOptionInstructions', + 'euiSelectableListItem.uncheckOptionInstructions': i18n.translate( + 'core.euiSelectableListItem.uncheckOptionInstructions', { - defaultMessage: 'To exclude this option, press enter.', + defaultMessage: 'To uncheck this option, press Enter.', } ), - 'euiSelectableListItem.excludedOption': i18n.translate( - 'core.euiSelectableListItem.excludedOption', + 'euiSelectableListItem.excludeOptionInstructions': i18n.translate( + 'core.euiSelectableListItem.excludeOptionInstructions', { - defaultMessage: 'Excluded option.', + defaultMessage: 'To exclude this option, press Enter.', + } + ), + 'euiSelectableListItem.mixedOption': i18n.translate('core.euiSelectableListItem.mixedOption', { + defaultMessage: 'Mixed (indeterminate) option.', + }), + + 'euiSelectableListItem.mixedOptionInstructions': i18n.translate( + 'core.euiSelectableListItem.mixedOptionInstructions', + { + defaultMessage: 'To check this option for all, press Enter once.', } ), - 'euiSelectableListItem.excludedOptionInstructions': i18n.translate( - 'core.euiSelectableListItem.excludedOptionInstructions', + 'euiSelectableListItem.mixedOptionUncheckInstructions': i18n.translate( + 'core.euiSelectableListItem.mixedOptionUncheckInstructions', { - defaultMessage: 'To uncheck this option, press enter.', + defaultMessage: 'To uncheck this option for all, press Enter twice.', } ), - 'euiSelectableListItem.unckeckedOptionInstructions': i18n.translate( - 'core.euiSelectableListItem.unckeckedOptionInstructions', + 'euiSelectableListItem.mixedOptionExcludeInstructions': i18n.translate( + 'core.euiSelectableListItem.mixedOptionExcludeInstructions', { - defaultMessage: 'To select this option, press enter.', + defaultMessage: 'To exclude this option for all, press Enter twice.', } ), 'euiSelectableTemplateSitewide.loadingResults': i18n.translate( diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 08c33c4062398..313ea43261928 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -85,7 +85,7 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint '@elastic/ems-client@8.4.0': ['Elastic License 2.0'], - '@elastic/eui@80.0.0': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/eui@81.0.0': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry 'buffers@0.1.1': ['MIT'], // license in importing module https://www.npmjs.com/package/binary }; diff --git a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx index e2fa74dfbf2f1..67c78b64f6066 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx @@ -100,7 +100,7 @@ describe('Options list popover', () => { '[data-test-subj="optionsList-control-available-options"] ul' ); availableOptions.children().forEach((child, i) => { - expect(child.text()).toBe(`${selections[i]} - Checked option.`); + expect(child.text()).toBe(`${selections[i]}. Checked option.`); }); }); @@ -134,7 +134,7 @@ describe('Options list popover', () => { }); const validSelection = findTestSubject(popover, 'optionsList-control-selection-bark'); expect(validSelection.find('.euiSelectableListItem__text').text()).toEqual( - 'bark - Checked option.' + 'bark. Checked option.' ); expect( validSelection.find('div[data-test-subj="optionsList-document-count-badge"]').text().trim() @@ -143,7 +143,7 @@ describe('Options list popover', () => { expect(title).toEqual('Ignored selection'); const invalidSelection = findTestSubject(popover, 'optionsList-control-ignored-selection-woof'); expect(invalidSelection.find('.euiSelectableListItem__text').text()).toEqual( - 'woof - Checked option.' + 'woof. Checked option.' ); expect(invalidSelection.hasClass('optionsList__selectionInvalid')).toBe(true); }); @@ -230,7 +230,7 @@ describe('Options list popover', () => { const availableOptions = popover.find( '[data-test-subj="optionsList-control-available-options"] ul' ); - expect(availableOptions.text()).toBe('Exists - Checked option.'); + expect(availableOptions.text()).toBe('Exists. Checked option.'); }); test('when sorting suggestions, show both sorting types for keyword field', async () => { @@ -244,7 +244,7 @@ describe('Options list popover', () => { const sortingOptionsDiv = findTestSubject(popover, 'optionsListControl__sortingOptions'); const optionsText = sortingOptionsDiv.find('ul li').map((element) => element.text().trim()); - expect(optionsText).toEqual(['By document count - Checked option.', 'Alphabetically']); + expect(optionsText).toEqual(['By document count. Checked option.', 'Alphabetically']); }); test('sorting popover selects appropriate sorting type on load', async () => { @@ -259,7 +259,7 @@ describe('Options list popover', () => { const sortingOptionsDiv = findTestSubject(popover, 'optionsListControl__sortingOptions'); const optionsText = sortingOptionsDiv.find('ul li').map((element) => element.text().trim()); - expect(optionsText).toEqual(['By document count', 'Alphabetically - Checked option.']); + expect(optionsText).toEqual(['By document count', 'Alphabetically. Checked option.']); const ascendingButton = findTestSubject(popover, 'optionsList__sortOrder_asc').instance(); expect(ascendingButton).toHaveClass('euiButtonGroupButton-isSelected'); @@ -276,7 +276,7 @@ describe('Options list popover', () => { const sortingOptionsDiv = findTestSubject(popover, 'optionsListControl__sortingOptions'); const optionsText = sortingOptionsDiv.find('ul li').map((element) => element.text().trim()); - expect(optionsText).toEqual(['By document count - Checked option.']); + expect(optionsText).toEqual(['By document count. Checked option.']); }); test('ensure warning icon does not show up when testAllowExpensiveQueries = true/undefined', async () => { diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx index d0b3e4b9a111b..c7c3322f79636 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/page_controls.tsx @@ -59,8 +59,8 @@ export const PageControlsComponent: FC = ({ const currentPage = page + 1; return ( - - + + = ({ aria-label="Next Page" /> - - + + ); }; diff --git a/x-pack/plugins/lens/public/datasources/form_based/layerpanel.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/layerpanel.test.tsx index f9d0dc9d8b9fb..eef44faaec8ff 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/layerpanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/layerpanel.test.tsx @@ -30,7 +30,7 @@ jest.mock('@kbn/unified-search-plugin/public', () => { interface IndexPatternPickerOption { label: string; - checked?: 'on' | 'off'; + checked?: 'on' | 'off' | 'mixed'; } const fieldsOne = [ diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts index 0c10a9da5d3e8..549b46a0b886e 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts @@ -94,6 +94,7 @@ import { getAvailablePrebuiltRulesCount } from '../../tasks/api_calls/prebuilt_r import { setRowsPerPageTo } from '../../tasks/table_pagination'; const RULE_NAME = 'Custom rule for bulk actions'; +const EUI_SELECTABLE_LIST_ITEM_SR_TEXT = '. To check this option, press Enter.'; const prePopulatedIndexPatterns = ['index-1-*', 'index-2-*']; const prePopulatedTags = ['test-default-tag-1', 'test-default-tag-2']; @@ -248,7 +249,7 @@ describe('Detection rules, bulk edit', () => { const resultingTags = [...prePopulatedTags, ...tagsToBeAdded]; // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags); + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); selectNumberOfRules(expectedNumberOfCustomRulesToBeEdited); @@ -264,14 +265,14 @@ describe('Detection rules, bulk edit', () => { // check that new tags were added to tags filter // tags in tags filter sorted alphabetically const resultingTagsInFilter = [...resultingTags].sort(); - checkTagsInTagsFilter(resultingTagsInFilter); + checkTagsInTagsFilter(resultingTagsInFilter, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); }); it('Display success toast after adding tags', () => { const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags); + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); selectNumberOfRules(expectedNumberOfCustomRulesToBeEdited); @@ -286,7 +287,7 @@ describe('Detection rules, bulk edit', () => { const tagsToOverwrite = ['overwrite-tag-1']; // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags); + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); selectNumberOfRules(expectedNumberOfCustomRulesToBeEdited); @@ -307,7 +308,7 @@ describe('Detection rules, bulk edit', () => { testAllTagsBadges(tagsToOverwrite); // check that only new tags are in the tag filter - checkTagsInTagsFilter(tagsToOverwrite); + checkTagsInTagsFilter(tagsToOverwrite, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); }); it('Delete tags from custom rules', () => { @@ -315,7 +316,7 @@ describe('Detection rules, bulk edit', () => { const resultingTags = prePopulatedTags.slice(1); // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags); + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); selectNumberOfRules(expectedNumberOfCustomRulesToBeEdited); @@ -329,7 +330,7 @@ describe('Detection rules, bulk edit', () => { testAllTagsBadges(resultingTags); // check that tags were removed from the tag filter - checkTagsInTagsFilter(resultingTags); + checkTagsInTagsFilter(resultingTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); }); }); 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 66f61cc0898f1..eac0dd5db5fb6 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 @@ -146,7 +146,7 @@ export const RULES_TAGS_FILTER_BTN = '[data-test-subj="tags-filter-popover-butto export const RULES_TAGS_FILTER_POPOVER = '[data-test-subj="tags-filter-popover"]'; -export const RULES_SELECTED_TAG = '.euiSelectableListItem[data-test-selected="true"]'; +export const RULES_SELECTED_TAG = '.euiSelectableListItem[aria-checked="true"]'; export const SELECTED_RULES_NUMBER_LABEL = '[data-test-subj="selectedRules"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/rules_bulk_edit.ts b/x-pack/plugins/security_solution/cypress/tasks/rules_bulk_edit.ts index d002b27bff582..010a587cf1019 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/rules_bulk_edit.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/rules_bulk_edit.ts @@ -244,14 +244,15 @@ export const selectTimelineTemplate = (timelineTitle: string) => { /** * check if rule tags filter populated with a list of tags * @param tags + * @param srOnlyText SR-only text appended by EUI */ -export const checkTagsInTagsFilter = (tags: string[]) => { +export const checkTagsInTagsFilter = (tags: string[], srOnlyText: string = '') => { cy.get(RULES_TAGS_FILTER_BTN).contains(`Tags${tags.length}`).click(); cy.get(EUI_SELECTABLE_LIST_ITEM) .should('have.length', tags.length) .each(($el, index) => { - cy.wrap($el).should('have.text', tags[index]); + cy.wrap($el).should('have.text', `${tags[index]}${srOnlyText}`); }); }; diff --git a/x-pack/plugins/security_solution/public/management/components/effected_policy_select/test_utils.ts b/x-pack/plugins/security_solution/public/management/components/effected_policy_select/test_utils.ts index cea51481bbd12..0c9b0a2e0da97 100644 --- a/x-pack/plugins/security_solution/public/management/components/effected_policy_select/test_utils.ts +++ b/x-pack/plugins/security_solution/public/management/components/effected_policy_select/test_utils.ts @@ -93,5 +93,5 @@ export const isEffectedPolicySelected = async ( throw new Error(`No policy found in EffectedPolicySelect at index position ${atIndex}`); } - return item.dataset.testSelected === 'true'; + return item.getAttribute('aria-checked') === 'true'; }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx index f437ef224d78e..49978e7958f4e 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx @@ -1089,14 +1089,14 @@ describe('Response actions history', () => { RESPONSE_ACTION_API_COMMANDS_NAMES.length ); expect(getAllByTestId(`${filterPrefix}-option`).map((option) => option.textContent)).toEqual([ - 'isolate', - 'release', - 'kill-process', - 'suspend-process', - 'processes', - 'get-file', - 'execute', - 'upload', + 'isolate. To check this option, press Enter.', + 'release. To check this option, press Enter.', + 'kill-process. To check this option, press Enter.', + 'suspend-process. To check this option, press Enter.', + 'processes. To check this option, press Enter.', + 'get-file. To check this option, press Enter.', + 'execute. To check this option, press Enter.', + 'upload. To check this option, press Enter.', ]); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx index 2b9a8f434f1cc..7c1a4c730363e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx @@ -14,7 +14,6 @@ import { EuiLoadingSpinner, EuiBottomBar, EuiSpacer, - EuiThemeProvider, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; @@ -167,18 +166,16 @@ export const PolicyFormLayout = React.memo(() => { - - - - - + + + {showEditableFormFields && ( diff --git a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx index 20f94a83de00b..5a98765b46d44 100644 --- a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx @@ -223,7 +223,10 @@ describe('Response actions history page', () => { }, []); expect(selectedFilterOptions.length).toEqual(2); - expect(selectedFilterOptions).toEqual(['release', 'processes']); + expect(selectedFilterOptions).toEqual([ + 'release. Checked option. To uncheck this option, press Enter.', + 'processes. Checked option. To uncheck this option, press Enter.', + ]); expect(history.location.search).toEqual('?commands=release,processes'); }); @@ -263,10 +266,10 @@ describe('Response actions history page', () => { expect(selectedFilterOptions.length).toEqual(4); expect(selectedFilterOptions).toEqual([ - 'Host-name-0', - 'Host-name-1', - 'Host-name-3', - 'Host-name-5', + 'Host-name-0. Checked option. To uncheck this option, press Enter.', + 'Host-name-1. Checked option. To uncheck this option, press Enter.', + 'Host-name-3. Checked option. To uncheck this option, press Enter.', + 'Host-name-5. Checked option. To uncheck this option, press Enter.', ]); expect(history.location.search).toEqual('?hosts=agent-id-1,agent-id-2,agent-id-4,agent-id-5'); }); @@ -290,7 +293,10 @@ describe('Response actions history page', () => { }, []); expect(selectedFilterOptions.length).toEqual(2); - expect(selectedFilterOptions).toEqual(['Failed', 'Pending']); + expect(selectedFilterOptions).toEqual([ + 'Failed. Checked option.', + 'Pending. Checked option.', + ]); expect(history.location.search).toEqual('?statuses=pending,failed'); }); diff --git a/x-pack/plugins/serverless_search/public/application/components/overview_panels/integrations_panel.tsx b/x-pack/plugins/serverless_search/public/application/components/overview_panels/integrations_panel.tsx index da8c7b97719f8..9ccf6867f11a7 100644 --- a/x-pack/plugins/serverless_search/public/application/components/overview_panels/integrations_panel.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/overview_panels/integrations_panel.tsx @@ -40,7 +40,7 @@ export const IntegrationsPanel: React.FC = () => { - +

{i18n.translate('xpack.serverlessSearch.ingestData.logstashDescription', { defaultMessage: @@ -82,7 +82,7 @@ export const IntegrationsPanel: React.FC = () => { - + {i18n.translate('xpack.serverlessSearch.ingestData.beatsDescription', { defaultMessage: 'Lightweight, single-purpose data shippers for Elasticsearch. Use Beats to send operational data from your servers.', @@ -122,7 +122,7 @@ export const IntegrationsPanel: React.FC = () => { - + {i18n.translate('xpack.serverlessSearch.ingestData.connectorsDescription', { defaultMessage: 'Specialized integrations for syncing data from third-party sources to Elasticsearch. Use Elastic Connectors to sync content from a range of databases and object stores.', diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index f38e6310626eb..ac7d24345abfb 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -861,12 +861,7 @@ "core.euiSelectable.placeholderName": "Options de filtre", "core.euiSelectable.screenReaderInstructions": "Utilisez les flèches vers le haut et vers le bas pour déplacer la mise au point sur les options. Appuyez sur Entrée pour sélectionner. Appuyez sur Échap pour réduire les options.", "core.euiSelectableListItem.checkedOption": "Option cochée.", - "core.euiSelectableListItem.checkedOptionInstructions": "Pour décocher cette option, appuyez sur Entrée.", "core.euiSelectableListItem.excludedOption": "Option exclue.", - "core.euiSelectableListItem.excludedOptionInstructions": "Pour décocher cette option, appuyez sur Entrée.", - "core.euiSelectableListItem.includedOption": "Option sélectionnée.", - "core.euiSelectableListItem.includedOptionInstructions": "Pour exclure cette option, appuyez sur Entrée.", - "core.euiSelectableListItem.unckeckedOptionInstructions": "Pour sélectionner cette option, appuyez sur Entrée.", "core.euiSelectableTemplateSitewide.loadingResults": "Chargement des résultats", "core.euiSelectableTemplateSitewide.noResults": "Aucun résultat disponible", "core.euiSelectableTemplateSitewide.onFocusBadgeGoTo": "Atteindre", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 82aebe0112589..be981b563a09e 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -861,12 +861,7 @@ "core.euiSelectable.placeholderName": "フィルターオプション", "core.euiSelectable.screenReaderInstructions": "オプションのフォーカスを移動するには、上下矢印キーを使用します。選択するには、Enterを押します。オプションを折りたたむには、Escapeを押します。", "core.euiSelectableListItem.checkedOption": "選択されたオプション。", - "core.euiSelectableListItem.checkedOptionInstructions": "このオプションをオフにするには、Enterを押します。", "core.euiSelectableListItem.excludedOption": "除外されたオプション。", - "core.euiSelectableListItem.excludedOptionInstructions": "このオプションをオフにするには、Enterを押します。", - "core.euiSelectableListItem.includedOption": "選択されたオプション。", - "core.euiSelectableListItem.includedOptionInstructions": "このオプションを除外するには、Enterを押します", - "core.euiSelectableListItem.unckeckedOptionInstructions": "このオプションをオンにするには、Enterを押します。", "core.euiSelectableTemplateSitewide.loadingResults": "結果を読み込み中", "core.euiSelectableTemplateSitewide.noResults": "結果がありません", "core.euiSelectableTemplateSitewide.onFocusBadgeGoTo": "移動:", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 1e4bec4f2bdd9..94ef77904ef4e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -861,12 +861,7 @@ "core.euiSelectable.placeholderName": "筛选选项", "core.euiSelectable.screenReaderInstructions": "使用向上和向下箭头键将焦点移到选项上。按 Enter 键进行选择。按 Esc 键折叠选项。", "core.euiSelectableListItem.checkedOption": "选中的选项。", - "core.euiSelectableListItem.checkedOptionInstructions": "要取消选中此选项,请按 Enter 键。", "core.euiSelectableListItem.excludedOption": "排除的选项。", - "core.euiSelectableListItem.excludedOptionInstructions": "要取消选中此选项,请按 Enter 键。", - "core.euiSelectableListItem.includedOption": "选定的选项。", - "core.euiSelectableListItem.includedOptionInstructions": "要排除此选项,请按 Enter 键。", - "core.euiSelectableListItem.unckeckedOptionInstructions": "要选择此选项,请按 Enter 键。", "core.euiSelectableTemplateSitewide.loadingResults": "正在加载结果", "core.euiSelectableTemplateSitewide.noResults": "没有可用结果", "core.euiSelectableTemplateSitewide.onFocusBadgeGoTo": "前往", diff --git a/x-pack/test/functional/services/ml/stack_management_jobs.ts b/x-pack/test/functional/services/ml/stack_management_jobs.ts index 20b901f94ca9e..081f80e4040b2 100644 --- a/x-pack/test/functional/services/ml/stack_management_jobs.ts +++ b/x-pack/test/functional/services/ml/stack_management_jobs.ts @@ -176,7 +176,7 @@ export function MachineLearningStackManagementJobsProvider({ async isSpaceSelectionRowSelected(spaceId: string): Promise { const state = await testSubjects.getAttribute( `sts-space-selector-row-${spaceId}`, - 'data-test-selected', + 'aria-checked', 1000 ); return state === 'true'; diff --git a/yarn.lock b/yarn.lock index ffaaf94858f9c..b160dff2202a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1552,13 +1552,13 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@80.0.0": - version "80.0.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-80.0.0.tgz#33e1df8a3f193fb6a7a4f7e52a3028983856ba3a" - integrity sha512-0xWizIQ/kH9N2n9zOficqXPdRbVxCpHez2ZErnvISAEOneJ6401usI7fILGKrrvR+uyiYnNybfaP3H8HcgDa+g== +"@elastic/eui@81.0.0": + version "81.0.0" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-81.0.0.tgz#819cedbd837ae96c05aed79c285f7b98f079dbf0" + integrity sha512-S7KaB5PhpY4KBIQT5pdtUukeSt2xsheWhl98FAEbVIcII1YUfOaGbk2rZC50Z7jn8t8KKQidjehCiLhxaYZTrA== dependencies: "@types/chroma-js" "^2.0.0" - "@types/lodash" "^4.14.160" + "@types/lodash" "^4.14.194" "@types/numeral" "^0.0.28" "@types/react-beautiful-dnd" "^13.1.2" "@types/react-input-autosize" "^2.2.1" @@ -8661,16 +8661,16 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.159.tgz#61089719dc6fdd9c5cb46efc827f2571d1517065" integrity sha512-gF7A72f7WQN33DpqOWw9geApQPh4M3PxluMtaHxWHXEGSN12/WbcEk/eNSqWNQcQhF66VSZ06vCF94CrHwXJDg== -"@types/lodash@^4.14.160": - version "4.14.161" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.161.tgz#a21ca0777dabc6e4f44f3d07f37b765f54188b18" - integrity sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA== - "@types/lodash@^4.14.167": version "4.14.184" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.184.tgz#23f96cd2a21a28e106dc24d825d4aa966de7a9fe" integrity sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q== +"@types/lodash@^4.14.194": + version "4.14.194" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.194.tgz#b71eb6f7a0ff11bff59fc987134a093029258a76" + integrity sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g== + "@types/long@^4.0.0", "@types/long@^4.0.1": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" From ccf00994708a6019b00ced51cf8456043fbcb1b3 Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Wed, 31 May 2023 15:37:01 -0400 Subject: [PATCH 03/31] [Security Solution][Endpoint] Improve dev tool so that incomplete agent downloads are deleted from disk cache (#158682) ## Summary - Adds logic to the Agent Download services (part of dev scripts) so that if the process is interrupted (ex. `SIGNINT` signal from CLI), any download currently in flight will be deleted from disk, thus avoiding storing agent download files that are incomplete and invalid. --- .../common/agent_downloads_service.ts | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/agent_downloads_service.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/agent_downloads_service.ts index ed5d0296d61a4..a14f8af1ef699 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/agent_downloads_service.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/agent_downloads_service.ts @@ -85,9 +85,16 @@ class AgentDownloadStorage extends SettingsStorage try { const outputStream = fs.createWriteStream(newDownloadInfo.fullFilePath); - const { body } = await nodeFetch(agentDownloadUrl); - await finished(body.pipe(outputStream)); + await handleProcessInterruptions( + async () => { + const { body } = await nodeFetch(agentDownloadUrl); + await finished(body.pipe(outputStream)); + }, + () => { + fs.unlinkSync(newDownloadInfo.fullFilePath); + } + ); } catch (e) { // Try to clean up download case it failed halfway through await unlink(newDownloadInfo.fullFilePath); @@ -134,6 +141,42 @@ class AgentDownloadStorage extends SettingsStorage } } +const handleProcessInterruptions = async ( + runFn: (() => T) | (() => Promise), + /** The synchronous cleanup callback */ + cleanup: () => void +): Promise => { + const eventNames = ['SIGINT', 'exit', 'uncaughtException', 'unhandledRejection']; + const stopListeners = () => { + for (const eventName of eventNames) { + process.off(eventName, cleanup); + } + }; + + for (const eventName of eventNames) { + process.on(eventName, cleanup); + } + + let runnerResponse: T | Promise; + + try { + runnerResponse = runFn(); + } catch (e) { + stopListeners(); + throw e; + } + + if ('finally' in runnerResponse) { + (runnerResponse as Promise).finally(() => { + stopListeners(); + }); + } else { + stopListeners(); + } + + return runnerResponse; +}; + const agentDownloadsClient = new AgentDownloadStorage(); /** From 3e3419d6c914ac01c71514f9cf4f065d62a5ba2b Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 31 May 2023 13:39:20 -0600 Subject: [PATCH 04/31] [Controls] Add ability to recover from non-fatal error state (#158087) Closes https://github.com/elastic/kibana/issues/156430 ## Summary The only reason a control embeddable should enter a fatal error state is if, for some reason, the embeddable actually cannot be created (for example, trying to create a control with a type that doesn't exist) - every other error should be considered **recoverable** as much as possible. So, this PR ensures that both the options list and the range slider are able to recover from most errors by switching from calling `onFatalError` to instead handling most errors internally via component state. > **Note** > The time slider control does not have any errors that would be considered "recoverable" because it is actually **much more difficult** to enter an error state for this control; so, I did not need to change anything for this control type. ### Errors: - **Recoverable error:** - **Before:** https://github.com/elastic/kibana/assets/8698078/7737a3e8-1c97-47ba-92ab-55f5e1a6c30a - **After:** https://github.com/elastic/kibana/assets/8698078/e4ced721-2b84-497e-8608-965877409bf5 - **Unrecoverable error:** To test this, I've created a dashboard saved object with a control type that does not exist: [controlTypeDoesNotExistDashboard.ndjson.zip](https://github.com/elastic/kibana/files/11547128/controlTypeDoesNotExistDashboard.ndjson.zip). Try importing this dashboard and ensure that you can actually see an error unlike the "before" state: - **Before:** ![image](https://github.com/elastic/kibana/assets/8698078/27c581b1-3fa8-4c07-b102-c952355dfd32) - **After:** ![image](https://github.com/elastic/kibana/assets/8698078/626ed696-4f8e-44b2-b449-3c2fa1ee1327) ### Flaky Test Runner - [Options list dashboard interavction (`test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts`)](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2316) ![image](https://github.com/elastic/kibana/assets/8698078/6b71c71c-a47b-4e84-834a-07b8c380a727) - [Range slider (`test/functional/apps/dashboard_elements/controls/range_slider.ts`)](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2317) ![image](https://github.com/elastic/kibana/assets/8698078/fe1c9752-68d3-4bca-b31a-361217b91d8e) ### 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 - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../component/control_error_component.tsx | 57 +++++++++++++++ .../component/control_frame_component.tsx | 60 +-------------- .../public/control_group/control_group.scss | 7 -- .../components/options_list_control.tsx | 6 +- .../embeddable/options_list_embeddable.tsx | 17 ++--- .../options_list/options_list_reducers.ts | 6 ++ .../controls/public/options_list/types.ts | 1 + .../components/range_slider_control.tsx | 7 +- .../embeddable/range_slider_embeddable.tsx | 73 ++++++++++++------- .../range_slider/range_slider_reducers.ts | 6 ++ .../controls/public/range_slider/types.ts | 1 + .../public/lib/embeddables/embeddable.tsx | 5 ++ .../render_complete_dispatcher.ts | 1 - .../components/field_picker/field_picker.scss | 6 +- .../options_list_dashboard_interaction.ts | 42 ++++++----- .../controls/range_slider.ts | 27 ++++++- 16 files changed, 194 insertions(+), 128 deletions(-) create mode 100644 src/plugins/controls/public/control_group/component/control_error_component.tsx diff --git a/src/plugins/controls/public/control_group/component/control_error_component.tsx b/src/plugins/controls/public/control_group/component/control_error_component.tsx new file mode 100644 index 0000000000000..409455f0e304e --- /dev/null +++ b/src/plugins/controls/public/control_group/component/control_error_component.tsx @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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, { useState } from 'react'; + +import { EuiButtonEmpty, EuiPopover } from '@elastic/eui'; +import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; +import { Markdown } from '@kbn/kibana-react-plugin/public'; + +interface ControlErrorProps { + error: Error | string; +} + +export const ControlError = ({ error }: ControlErrorProps) => { + const [isPopoverOpen, setPopoverOpen] = useState(false); + const errorMessage = error instanceof Error ? error.message : error; + + const popoverButton = ( + setPopoverOpen((open) => !open)} + className={'errorEmbeddableCompact__button'} + textProps={{ className: 'errorEmbeddableCompact__text' }} + > + + + ); + + return ( + + setPopoverOpen(false)} + > + + + + ); +}; diff --git a/src/plugins/controls/public/control_group/component/control_frame_component.tsx b/src/plugins/controls/public/control_group/component/control_frame_component.tsx index 49282b05d76f9..6cb9a9b0cb970 100644 --- a/src/plugins/controls/public/control_group/component/control_frame_component.tsx +++ b/src/plugins/controls/public/control_group/component/control_frame_component.tsx @@ -10,16 +10,13 @@ import classNames from 'classnames'; import React, { useEffect, useMemo, useState } from 'react'; import { - EuiButtonEmpty, EuiFormControlLayout, EuiFormLabel, EuiFormRow, EuiLoadingChart, - EuiPopover, EuiToolTip, } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { Markdown } from '@kbn/kibana-react-plugin/public'; +import { isErrorEmbeddable } from '@kbn/embeddable-plugin/public'; import { FloatingActions } from '@kbn/presentation-util-plugin/public'; import { @@ -28,45 +25,7 @@ import { } from '../embeddable/control_group_container'; import { ControlGroupStrings } from '../control_group_strings'; import { useChildEmbeddable } from '../../hooks/use_child_embeddable'; - -interface ControlFrameErrorProps { - error: Error; -} - -const ControlFrameError = ({ error }: ControlFrameErrorProps) => { - const [isPopoverOpen, setPopoverOpen] = useState(false); - const popoverButton = ( - setPopoverOpen((open) => !open)} - className={'errorEmbeddableCompact__button'} - textProps={{ className: 'errorEmbeddableCompact__text' }} - > - - - ); - - return ( - setPopoverOpen(false)} - > - - - ); -}; +import { ControlError } from './control_error_component'; export interface ControlFrameProps { customPrepend?: JSX.Element; @@ -82,7 +41,6 @@ export const ControlFrame = ({ embeddableType, }: ControlFrameProps) => { const embeddableRoot: React.RefObject = useMemo(() => React.createRef(), []); - const [fatalError, setFatalError] = useState(); const controlGroup = useControlGroupContainer(); @@ -107,19 +65,14 @@ export const ControlFrame = ({ const inputSubscription = embeddable ?.getInput$() .subscribe((newInput) => setTitle(newInput.title)); - const errorSubscription = embeddable?.getOutput$().subscribe({ - error: setFatalError, - }); return () => { inputSubscription?.unsubscribe(); - errorSubscription?.unsubscribe(); }; }, [embeddable, embeddableRoot]); const embeddableParentClassNames = classNames('controlFrame__control', { 'controlFrame--twoLine': controlStyle === 'twoLine', 'controlFrame--oneLine': controlStyle === 'oneLine', - 'controlFrame--fatalError': !!fatalError, }); function renderEmbeddablePrepend() { @@ -149,18 +102,13 @@ export const ControlFrame = ({ } > - {embeddable && !fatalError && ( + {embeddable && (

- {fatalError && } -
- )} - {fatalError && ( -
- {} + {isErrorEmbeddable(embeddable) && }
)} {!embeddable && ( diff --git a/src/plugins/controls/public/control_group/control_group.scss b/src/plugins/controls/public/control_group/control_group.scss index e0bb26b57c820..82bf3a3d1c854 100644 --- a/src/plugins/controls/public/control_group/control_group.scss +++ b/src/plugins/controls/public/control_group/control_group.scss @@ -205,11 +205,4 @@ $controlMinWidth: $euiSize * 14; &--twoLine { top: (-$euiSizeXS) !important; } - - &--fatalError { - padding: $euiSizeXS; - border-radius: $euiBorderRadius; - background-color: $euiColorEmptyShade; - box-shadow: 0 0 0 1px $euiColorLightShade; - } } diff --git a/src/plugins/controls/public/options_list/components/options_list_control.tsx b/src/plugins/controls/public/options_list/components/options_list_control.tsx index 7d899f8a90e31..0df08a69eb4d5 100644 --- a/src/plugins/controls/public/options_list/components/options_list_control.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_control.tsx @@ -19,6 +19,7 @@ import { OptionsListPopover } from './options_list_popover'; import { useOptionsList } from '../embeddable/options_list_embeddable'; import './options_list.scss'; +import { ControlError } from '../../control_group/component/control_error_component'; export const OptionsListControl = ({ typeaheadSubject, @@ -31,6 +32,7 @@ export const OptionsListControl = ({ const optionsList = useOptionsList(); const dimensions = useResizeObserver(resizeRef.current); + const error = optionsList.select((state) => state.componentState.error); const isPopoverOpen = optionsList.select((state) => state.componentState.popoverOpen); const validSelections = optionsList.select((state) => state.componentState.validSelections); const invalidSelections = optionsList.select((state) => state.componentState.invalidSelections); @@ -143,7 +145,9 @@ export const OptionsListControl = ({ ); - return ( + return error ? ( + + ) : ( { + this.dispatch.setErrorMessage(undefined); this.dispatch.setLoading(false); this.dispatch.publishFilters(newFilters); }); } else { batch(() => { + this.dispatch.setErrorMessage(undefined); this.dispatch.updateQueryResults({ availableOptions: [], }); @@ -412,14 +414,6 @@ export class OptionsListEmbeddable extends Embeddable { - batch(() => { - this.dispatch.setLoading(false); - this.dispatch.setPopoverOpen(false); - }); - super.onFatalError(e); - }; - public destroy = () => { super.destroy(); this.cleanupStateTools(); @@ -433,6 +427,7 @@ export class OptionsListEmbeddable extends Embeddable diff --git a/src/plugins/controls/public/options_list/options_list_reducers.ts b/src/plugins/controls/public/options_list/options_list_reducers.ts index f50ab9bd6f7f7..868a831370f46 100644 --- a/src/plugins/controls/public/options_list/options_list_reducers.ts +++ b/src/plugins/controls/public/options_list/options_list_reducers.ts @@ -103,6 +103,12 @@ export const optionsListReducers = { state.componentState.invalidSelections = invalidSelections; state.componentState.validSelections = validSelections; }, + setErrorMessage: ( + state: WritableDraft, + action: PayloadAction + ) => { + state.componentState.error = action.payload; + }, setLoading: (state: WritableDraft, action: PayloadAction) => { state.output.loading = action.payload; }, diff --git a/src/plugins/controls/public/options_list/types.ts b/src/plugins/controls/public/options_list/types.ts index c0501b0b6f38b..30b561d5e7964 100644 --- a/src/plugins/controls/public/options_list/types.ts +++ b/src/plugins/controls/public/options_list/types.ts @@ -33,6 +33,7 @@ export interface OptionsListComponentState { totalCardinality?: number; popoverOpen: boolean; field?: FieldSpec; + error?: string; } // public only - redux embeddable state type diff --git a/src/plugins/controls/public/range_slider/components/range_slider_control.tsx b/src/plugins/controls/public/range_slider/components/range_slider_control.tsx index c96637b55f1d7..e483cf4bb16ae 100644 --- a/src/plugins/controls/public/range_slider/components/range_slider_control.tsx +++ b/src/plugins/controls/public/range_slider/components/range_slider_control.tsx @@ -21,6 +21,7 @@ import { useRangeSlider } from '../embeddable/range_slider_embeddable'; import { RangeSliderPopover, EuiDualRangeRef } from './range_slider_popover'; import './range_slider.scss'; +import { ControlError } from '../../control_group/component/control_error_component'; const INVALID_CLASS = 'rangeSliderAnchor__fieldNumber--invalid'; @@ -32,7 +33,9 @@ export const RangeSliderControl: FC = () => { const min = rangeSlider.select((state) => state.componentState.min); const max = rangeSlider.select((state) => state.componentState.max); + const error = rangeSlider.select((state) => state.componentState.error); const isInvalid = rangeSlider.select((state) => state.componentState.isInvalid); + const id = rangeSlider.select((state) => state.explicitInput.id); const value = rangeSlider.select((state) => state.explicitInput.value) ?? ['', '']; const isLoading = rangeSlider.select((state) => state.output.loading); @@ -116,7 +119,9 @@ export const RangeSliderControl: FC = () => { ); - return ( + return error ? ( + + ) : ( { - if (initialValue) { - this.setInitializationFinished(); - } - this.setupSubscriptions(); - }); + this.runRangeSliderQuery() + .catch((e) => { + batch(() => { + this.dispatch.setLoading(false); + this.dispatch.setErrorMessage(e.message); + }); + }) + .then(async () => { + if (initialValue) { + this.setInitializationFinished(); + } + this.setupSubscriptions(); + }); }; private setupSubscriptions = () => { @@ -161,7 +168,13 @@ export class RangeSliderEmbeddable extends Embeddable + this.runRangeSliderQuery().catch((e) => { + this.dispatch.setErrorMessage(e.message); + }) + ) + ); // build filters when value change this.subscriptions.add( @@ -186,7 +199,6 @@ export class RangeSliderEmbeddable extends Embeddable { this.dispatch.setLoading(true); + const { dataView, field } = await this.getCurrentDataViewAndField(); if (!dataView || !field) return; @@ -268,15 +282,18 @@ export class RangeSliderEmbeddable extends Embeddable { + throw e; }); this.dispatch.setMinMax({ min: `${min ?? ''}`, max: `${max ?? ''}`, }); - // build filter with new min/max - await this.buildFilter(); + await this.buildFilter().catch((e) => { + throw e; + }); }; private fetchMinMax = async ({ @@ -321,11 +338,11 @@ export class RangeSliderEmbeddable extends Embeddable { + throw e; + }); const min = get(resp, 'rawResponse.aggregations.minAgg.value', ''); const max = get(resp, 'rawResponse.aggregations.maxAgg.value', ''); @@ -343,7 +360,6 @@ export class RangeSliderEmbeddable extends Embeddable { - this.runRangeSliderQuery(); + this.runRangeSliderQuery().catch((e) => { + this.dispatch.setErrorMessage(e.message); + }); }; public destroy = () => { diff --git a/src/plugins/controls/public/range_slider/range_slider_reducers.ts b/src/plugins/controls/public/range_slider/range_slider_reducers.ts index 074345d40596d..e8fcf0a10b2c3 100644 --- a/src/plugins/controls/public/range_slider/range_slider_reducers.ts +++ b/src/plugins/controls/public/range_slider/range_slider_reducers.ts @@ -40,6 +40,12 @@ export const rangeSliderReducers = { ) => { state.output.dataViewId = action.payload; }, + setErrorMessage: ( + state: WritableDraft, + action: PayloadAction + ) => { + state.componentState.error = action.payload; + }, setLoading: (state: WritableDraft, action: PayloadAction) => { state.output.loading = action.payload; }, diff --git a/src/plugins/controls/public/range_slider/types.ts b/src/plugins/controls/public/range_slider/types.ts index bf0064fa37665..ad321271631e0 100644 --- a/src/plugins/controls/public/range_slider/types.ts +++ b/src/plugins/controls/public/range_slider/types.ts @@ -17,6 +17,7 @@ export interface RangeSliderComponentState { field?: FieldSpec; min: string; max: string; + error?: string; isInvalid?: boolean; } diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index 75c666d4e2903..695c23fa0a2e2 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -277,6 +277,11 @@ export abstract class Embeddable< } } + /** + * Call this **only** when your embeddable has encountered a non-recoverable error; recoverable errors + * should be handled by the individual embeddable types + * @param e The fatal, unrecoverable Error that was thrown + */ protected onFatalError(e: Error) { this.fatalError = e; this.outputSubject.error(e); diff --git a/src/plugins/kibana_utils/public/render_complete/render_complete_dispatcher.ts b/src/plugins/kibana_utils/public/render_complete/render_complete_dispatcher.ts index 8ae5cfbe0ca84..597ddcaefc500 100644 --- a/src/plugins/kibana_utils/public/render_complete/render_complete_dispatcher.ts +++ b/src/plugins/kibana_utils/public/render_complete/render_complete_dispatcher.ts @@ -64,7 +64,6 @@ export class RenderCompleteDispatcher { if (!this.el) return; this.count++; this.el.setAttribute('data-render-complete', 'true'); - this.el.setAttribute('data-loading', 'false'); this.el.setAttribute('data-rendering-count', String(this.count)); } diff --git a/src/plugins/presentation_util/public/components/field_picker/field_picker.scss b/src/plugins/presentation_util/public/components/field_picker/field_picker.scss index cb81739118249..74e29b409b5f4 100644 --- a/src/plugins/presentation_util/public/components/field_picker/field_picker.scss +++ b/src/plugins/presentation_util/public/components/field_picker/field_picker.scss @@ -6,9 +6,7 @@ .fieldPickerSelectable { height: $euiSizeXXL * 9; // 40 * 9 = 360px - &.fieldPickerSelectableLoading { - .euiSelectableMessage { - height: 100%; - } + .euiSelectableMessage { + height: 100%; } } \ No newline at end of file diff --git a/test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts b/test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts index bda198fc16e8b..fd506429ba54f 100644 --- a/test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts +++ b/test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_interaction.ts @@ -16,7 +16,6 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; import { OPTIONS_LIST_DASHBOARD_NAME } from '.'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const retry = getService('retry'); const queryBar = getService('queryBar'); const pieChart = getService('pieChart'); const elasticChart = getService('elasticChart'); @@ -45,6 +44,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await elasticChart.setNewChartUiDebugFlag(); await dashboard.loadSavedDashboard(OPTIONS_LIST_DASHBOARD_NAME); await dashboard.ensureDashboardIsInEditMode(); + await header.waitUntilLoadingHasFinished(); }; before(async () => { @@ -67,12 +67,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); describe('Applies query settings to controls', async () => { - it('Applies dashboard query to options list control', async () => { - await queryBar.setQuery('animal.keyword : "dog" '); + it('Malformed query throws an error', async () => { + await queryBar.setQuery('animal.keyword : "dog" error'); await queryBar.submitQuery(); // quicker than clicking the submit button, but hides the time picker - await dashboard.waitForRenderComplete(); await header.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail('control-frame-error'); + }); + it('Can recover from malformed query error', async () => { + await queryBar.setQuery('animal.keyword : "dog"'); + await queryBar.submitQuery(); + await header.waitUntilLoadingHasFinished(); + await testSubjects.missingOrFail('control-frame-error'); + }); + + it('Applies dashboard query to options list control', async () => { const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ 'ruff', 'bark', @@ -85,7 +94,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { invalidSelections: [], }); await queryBar.setQuery(''); - await queryBar.clickQuerySubmitButton(); // ensures that the time picker is visible for the next test + await queryBar.clickQuerySubmitButton(); // slower than submitQuery but ensures that the time picker is visible for the next test }); it('Applies dashboard time range to options list control', async () => { @@ -94,7 +103,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'Jan 1, 2017 @ 00:00:00.000', 'Jan 1, 2017 @ 00:00:00.000' ); - await dashboard.waitForRenderComplete(); await header.waitUntilLoadingHasFinished(); await dashboardControls.optionsListOpenPopover(controlId); @@ -110,7 +118,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { operation: 'is one of', value: ['bark', 'bow ow ow', 'ruff'], }); - await dashboard.waitForRenderComplete(); await header.waitUntilLoadingHasFinished(); }); @@ -128,20 +135,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('Does not apply disabled dashboard filters to options list control', async () => { await filterBar.toggleFilterEnabled('sound.keyword'); - await dashboard.waitForRenderComplete(); await header.waitUntilLoadingHasFinished(); await dashboardControls.ensureAvailableOptionsEqual(controlId, { suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, invalidSelections: [], }); await filterBar.toggleFilterEnabled('sound.keyword'); - await dashboard.waitForRenderComplete(); await header.waitUntilLoadingHasFinished(); }); it('Negated filters apply to options control', async () => { await filterBar.toggleFilterNegated('sound.keyword'); - await dashboard.waitForRenderComplete(); await header.waitUntilLoadingHasFinished(); const suggestions = pick(OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, [ @@ -167,7 +171,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('Shows available options in options list', async () => { await queryBar.setQuery(''); await queryBar.submitQuery(); - await dashboard.waitForRenderComplete(); await header.waitUntilLoadingHasFinished(); await dashboardControls.ensureAvailableOptionsEqual(controlId, { suggestions: OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS, @@ -218,16 +221,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('Applies options list control options to dashboard', async () => { - await retry.try(async () => { - expect(await pieChart.getPieSliceCount()).to.be(2); - }); + await dashboard.waitForRenderComplete(); + expect(await pieChart.getPieSliceCount()).to.be(2); }); it('Applies options list control options to dashboard by default on open', async () => { await dashboard.gotoDashboardLandingPage(); await header.waitUntilLoadingHasFinished(); await dashboard.clickUnsavedChangesContinueEditing(OPTIONS_LIST_DASHBOARD_NAME); - await header.waitUntilLoadingHasFinished(); + await dashboard.waitForRenderComplete(); expect(await pieChart.getPieSliceCount()).to.be(2); const selectionString = await dashboardControls.optionsListGetSelectionsString(controlId); @@ -236,13 +238,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('excluding selections has expected results', async () => { await dashboard.clickQuickSave(); - await dashboard.waitForRenderComplete(); + await header.waitUntilLoadingHasFinished(); await dashboardControls.optionsListOpenPopover(controlId); await dashboardControls.optionsListPopoverSetIncludeSelections(false); await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); + await dashboard.waitForRenderComplete(); expect(await pieChart.getPieSliceCount()).to.be(5); await dashboard.clearUnsavedChanges(); }); @@ -251,8 +253,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboardControls.optionsListOpenPopover(controlId); await dashboardControls.optionsListPopoverSetIncludeSelections(true); await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); + await dashboard.waitForRenderComplete(); expect(await pieChart.getPieSliceCount()).to.be(2); await dashboard.clearUnsavedChanges(); }); @@ -339,8 +341,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboardControls.optionsListOpenPopover(controlId); await dashboardControls.optionsListPopoverSelectOption('B'); await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.waitForRenderComplete(); + await dashboard.waitForRenderComplete(); expect(await pieChart.getPieChartLabels()).to.eql(['bark', 'bow ow ow']); }); @@ -387,10 +389,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); controlId = (await dashboardControls.getAllControlIds())[0]; await header.waitUntilLoadingHasFinished(); - await dashboard.waitForRenderComplete(); }); it('creating exists query has expected results', async () => { + await dashboard.waitForRenderComplete(); expect((await pieChart.getPieChartValues())[0]).to.be(6); await dashboardControls.optionsListOpenPopover(controlId); await dashboardControls.optionsListPopoverSelectExists(); diff --git a/test/functional/apps/dashboard_elements/controls/range_slider.ts b/test/functional/apps/dashboard_elements/controls/range_slider.ts index fa075093fcbec..f1ccf742ad844 100644 --- a/test/functional/apps/dashboard_elements/controls/range_slider.ts +++ b/test/functional/apps/dashboard_elements/controls/range_slider.ts @@ -15,10 +15,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const esArchiver = getService('esArchiver'); const security = getService('security'); + const queryBar = getService('queryBar'); const filterBar = getService('filterBar'); const testSubjects = getService('testSubjects'); const kibanaServer = getService('kibanaServer'); - const { dashboardControls, timePicker, common, dashboard } = getPageObjects([ + const { dashboardControls, timePicker, common, dashboard, header } = getPageObjects([ 'dashboardControls', 'timePicker', 'dashboard', @@ -231,5 +232,29 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect((await testSubjects.getVisibleText('rangeSlider__helpText')).length).to.be.above(0); }); }); + + describe('interaction', async () => { + it('Malformed query throws an error', async () => { + await queryBar.setQuery('AvgTicketPrice <= 300 error'); + await queryBar.submitQuery(); + await header.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail('control-frame-error'); + }); + + it('Can recover from malformed query error', async () => { + await queryBar.setQuery('AvgTicketPrice <= 300'); + await queryBar.submitQuery(); + await header.waitUntilLoadingHasFinished(); + await testSubjects.missingOrFail('control-frame-error'); + }); + + it('Applies dashboard query to range slider control', async () => { + const firstId = (await dashboardControls.getAllControlIds())[0]; + await dashboardControls.rangeSliderWaitForLoading(); + await dashboardControls.validateRange('placeholder', firstId, '100', '300'); + await queryBar.setQuery(''); + await queryBar.submitQuery(); + }); + }); }); } From 6fd386c1444f57c5f8c464e94a6d41c3a014f4b2 Mon Sep 17 00:00:00 2001 From: Sergi Massaneda Date: Wed, 31 May 2023 21:57:58 +0200 Subject: [PATCH 05/31] [Security Solution] Remove legacy navigation and related logic (#158094) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit part of: https://github.com/elastic/kibana/issues/157847 closes: https://github.com/elastic/kibana/issues/145718 ### Background The new navigation became the default navigation for Security on 8.4. To have a smooth transition we added an advanced setting to use the old navigation. Since then the legacy navigation has become outdated, there are links in Security that are not accessible through it, such as the landing pages for the sub-sections: - `/security/dashboards` - `/security/explore` - `/security/manage` With the introduction of the new Security AI design, more of those landing pages that are not compatible with the legacy navigation design will be added (e.g. Rules). And it was starting to become overcrowded since there was no possibility to collapse groups. Also, over time it has become harder and harder to maintain both versions at the same time, all the new pages added to security were having to duplicate the navigation configurations for both versions and also test everything twice. On top of that, the legacy navigation won't be supported on the Security Serverless projects, everything will work with the new one exclusively. ## Docs The Security documentation assumes the new navigation is used everywhere, there's no mention of the old navigation, only one small section about the advanced setting (which is actually outdated): https://www.elastic.co/guide/en/security/8.7/advanced-settings.html#_enable_grouped_navigation Which will need to be removed for 8.9. ## Summary Cleans the old navigation and the advanced setting (`securitySolution:enableGroupedNav`) to turn it on. Removes the telemetry (which shows almost no usage of it) and external dependencies as well. Only the new navigation will be available. All links should work only with the `app_links` architecture from now on. Old Nav ❌ ![old_nav](https://github.com/elastic/kibana/assets/17747913/b95ff48c-73d4-45f6-93e5-8bec3fb24052) New nav ✅ ![new_nav](https://github.com/elastic/kibana/assets/17747913/8695c63e-df97-4ffc-b504-b4f48a366b3b) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../data_table/common/constants.ts | 501 -------- .../data_table/mock/mock_source.ts | 13 +- .../security_solution_links.test.ts | 16 +- .../navigation/security_solution_links.ts | 22 - x-pack/plugins/cloud_defend/public/index.ts | 5 +- .../security_solution_links.test.ts | 21 +- .../navigation/security_solution_links.ts | 22 - .../cloud_security_posture/public/index.ts | 5 +- .../security_solution/common/constants.ts | 3 - .../public/app/deep_links/index.test.ts | 195 --- .../public/app/deep_links/index.ts | 639 ---------- .../public/app/home/home_navigations.ts | 239 ---- .../app/home/template_wrapper/index.tsx | 11 +- .../landing_links_icons.test.tsx | 4 +- .../landing_links/landing_links_icons.tsx | 4 +- .../landing_links_images.test.tsx | 6 +- .../landing_links/landing_links_images.tsx | 4 +- .../breadcrumbs/get_breadcrumbs_for_page.ts | 19 +- .../navigation/breadcrumbs/index.test.ts | 1094 ++++++----------- .../navigation/breadcrumbs/index.ts | 74 +- .../common/components/navigation/helpers.ts | 11 - .../security_side_nav.test.tsx | 6 +- .../navigation/tab_navigation/index.tsx | 110 +- ...index.test.tsx => tab_navigation.test.tsx} | 39 +- .../tab_navigation/tab_navigation.tsx | 114 ++ .../navigation/tab_navigation/types.ts | 8 +- .../tab_navigation_with_breadcrumbs.test.tsx | 143 --- .../tab_navigation_with_breadcrumbs.tsx | 46 - .../common/components/navigation/types.ts | 76 +- .../__snapshots__/index.test.tsx.snap | 289 ----- .../index.test.tsx | 196 --- .../index.tsx | 44 +- .../use_security_solution_navigation/types.ts | 16 - .../use_navigation_items.tsx | 170 --- .../use_primary_navigation.tsx | 69 -- .../use_security_solution_navigation.test.tsx | 52 + .../use_security_solution_navigation.tsx | 45 + .../hooks/use_update_browser_title.test.ts | 34 - .../common/hooks/use_update_browser_title.ts | 16 +- .../public/common/lib/telemetry/index.ts | 1 - .../public/common/links/deep_links.ts | 41 + .../public/common/links/links.ts | 6 +- .../mock/endpoint/app_context_render.tsx | 26 +- .../utils/timeline/use_show_timeline.test.tsx | 165 +-- .../timeline/use_show_timeline_for_path.ts | 29 +- .../pages/landing_page/index.test.tsx | 4 +- .../pages/rule_details/index.tsx | 4 +- .../rules_table/rules_table_toolbar.tsx | 4 +- .../detections/pages/alert_details/index.tsx | 4 +- .../explore/hosts/pages/details/index.tsx | 4 +- .../public/explore/hosts/pages/hosts.test.tsx | 4 +- .../public/explore/hosts/pages/hosts.tsx | 4 +- .../explore/network/pages/details/index.tsx | 4 +- .../public/explore/network/pages/network.tsx | 4 +- .../explore/users/pages/details/index.tsx | 4 +- .../public/explore/users/pages/users.tsx | 4 +- .../explore/users/pages/users_tabs.test.tsx | 4 +- .../security_solution/public/plugin.tsx | 43 +- .../security_solution/server/ui_settings.ts | 18 - .../threat_intelligence/public/index.ts | 6 +- .../utils/security_solution_links.test.ts | 35 +- .../public/utils/security_solution_links.ts | 80 -- .../translations/translations/fr-FR.json | 35 - .../translations/translations/ja-JP.json | 35 - .../translations/translations/zh-CN.json | 35 - 65 files changed, 799 insertions(+), 4185 deletions(-) delete mode 100644 x-pack/packages/security-solution/data_table/common/constants.ts delete mode 100644 x-pack/plugins/security_solution/public/app/deep_links/index.test.ts delete mode 100644 x-pack/plugins/security_solution/public/app/deep_links/index.ts delete mode 100644 x-pack/plugins/security_solution/public/app/home/home_navigations.ts rename x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/{index.test.tsx => tab_navigation.test.tsx} (76%) create mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.test.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/types.ts delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/links/deep_links.ts diff --git a/x-pack/packages/security-solution/data_table/common/constants.ts b/x-pack/packages/security-solution/data_table/common/constants.ts deleted file mode 100644 index b2e623eebddb6..0000000000000 --- a/x-pack/packages/security-solution/data_table/common/constants.ts +++ /dev/null @@ -1,501 +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. - */ - -/** - * as const - * - * The const assertion ensures that type widening does not occur - * https://mariusschulz.com/blog/literal-type-widening-in-typescript - * Please follow this convention when adding to this file - */ - -export const APP_ID = 'securitySolution' as const; -export const APP_UI_ID = 'securitySolutionUI' as const; -export const CASES_FEATURE_ID = 'securitySolutionCases' as const; -export const SERVER_APP_ID = 'siem' as const; -export const APP_NAME = 'Security' as const; -export const APP_ICON = 'securityAnalyticsApp' as const; -export const APP_ICON_SOLUTION = 'logoSecurity' as const; -export const APP_PATH = `/app/security` as const; -export const ADD_DATA_PATH = `/app/integrations/browse/security`; -export const ADD_THREAT_INTELLIGENCE_DATA_PATH = `/app/integrations/browse/threat_intel`; -export const DEFAULT_BYTES_FORMAT = 'format:bytes:defaultPattern' as const; -export const DEFAULT_DATE_FORMAT = 'dateFormat' as const; -export const DEFAULT_DATE_FORMAT_TZ = 'dateFormat:tz' as const; -export const DEFAULT_DARK_MODE = 'theme:darkMode' as const; -export const DEFAULT_INDEX_KEY = 'securitySolution:defaultIndex' as const; -export const DEFAULT_NUMBER_FORMAT = 'format:number:defaultPattern' as const; -export const DEFAULT_DATA_VIEW_ID = 'security-solution' as const; -export const DEFAULT_TIME_FIELD = '@timestamp' as const; -export const DEFAULT_TIME_RANGE = 'timepicker:timeDefaults' as const; -export const DEFAULT_REFRESH_RATE_INTERVAL = 'timepicker:refreshIntervalDefaults' as const; -export const DEFAULT_APP_TIME_RANGE = 'securitySolution:timeDefaults' as const; -export const DEFAULT_APP_REFRESH_INTERVAL = 'securitySolution:refreshIntervalDefaults' as const; -export const DEFAULT_ALERTS_INDEX = '.alerts-security.alerts' as const; -export const DEFAULT_SIGNALS_INDEX = '.siem-signals' as const; -export const DEFAULT_PREVIEW_INDEX = '.preview.alerts-security.alerts' as const; -export const DEFAULT_LISTS_INDEX = '.lists' as const; -export const DEFAULT_ITEMS_INDEX = '.items' as const; -// The DEFAULT_MAX_SIGNALS value exists also in `x-pack/plugins/cases/common/constants.ts` -// If either changes, engineer should ensure both values are updated -export const DEFAULT_MAX_SIGNALS = 100 as const; -export const DEFAULT_SEARCH_AFTER_PAGE_SIZE = 100 as const; -export const DEFAULT_ANOMALY_SCORE = 'securitySolution:defaultAnomalyScore' as const; -export const DEFAULT_MAX_TABLE_QUERY_SIZE = 10000 as const; -export const DEFAULT_FROM = 'now/d' as const; -export const DEFAULT_TO = 'now/d' as const; -export const DEFAULT_INTERVAL_PAUSE = true as const; -export const DEFAULT_INTERVAL_TYPE = 'manual' as const; -export const DEFAULT_INTERVAL_VALUE = 300000 as const; // ms -export const DEFAULT_TIMEPICKER_QUICK_RANGES = 'timepicker:quickRanges' as const; -export const SCROLLING_DISABLED_CLASS_NAME = 'scrolling-disabled' as const; -export const FULL_SCREEN_TOGGLED_CLASS_NAME = 'fullScreenToggled' as const; -export const NO_ALERT_INDEX = 'no-alert-index-049FC71A-4C2C-446F-9901-37XMC5024C51' as const; -export const ENDPOINT_METADATA_INDEX = 'metrics-endpoint.metadata-*' as const; -export const ENDPOINT_METRICS_INDEX = '.ds-metrics-endpoint.metrics-*' as const; -export const DEFAULT_RULE_REFRESH_INTERVAL_ON = true as const; -export const DEFAULT_RULE_REFRESH_INTERVAL_VALUE = 60000 as const; // ms -export const DEFAULT_RULE_NOTIFICATION_QUERY_SIZE = 100 as const; -export const SECURITY_FEATURE_ID = 'Security' as const; -export const SECURITY_TAG_NAME = 'Security Solution' as const; -export const DEFAULT_SPACE_ID = 'default' as const; -export const DEFAULT_RELATIVE_DATE_THRESHOLD = 24 as const; - -// Document path where threat indicator fields are expected. Fields are used -// to enrich signals, and are copied to threat.enrichments. -export const DEFAULT_INDICATOR_SOURCE_PATH = 'threat.indicator' as const; -export const ENRICHMENT_DESTINATION_PATH = 'threat.enrichments' as const; -export const DEFAULT_THREAT_INDEX_KEY = 'securitySolution:defaultThreatIndex' as const; -export const DEFAULT_THREAT_INDEX_VALUE = ['logs-ti_*'] as const; -export const DEFAULT_THREAT_MATCH_QUERY = '@timestamp >= "now-30d/d"' as const; - -export enum SecurityPageName { - administration = 'administration', - alerts = 'alerts', - blocklist = 'blocklist', - /* - * Warning: Computed values are not permitted in an enum with string valued members - * All Cases page names must match `CasesDeepLinkId` in x-pack/plugins/cases/public/common/navigation/deep_links.ts - */ - case = 'cases', // must match `CasesDeepLinkId.cases` - caseConfigure = 'cases_configure', // must match `CasesDeepLinkId.casesConfigure` - caseCreate = 'cases_create', // must match `CasesDeepLinkId.casesCreate` - /* - * Warning: Computed values are not permitted in an enum with string valued members - * All cloud security posture page names must match `CloudSecurityPosturePageId` in x-pack/plugins/cloud_security_posture/public/common/navigation/types.ts - */ - cloudSecurityPostureBenchmarks = 'cloud_security_posture-benchmarks', - cloudSecurityPostureDashboard = 'cloud_security_posture-dashboard', - cloudSecurityPostureFindings = 'cloud_security_posture-findings', - cloudSecurityPostureRules = 'cloud_security_posture-rules', - dashboardsLanding = 'dashboards', - dataQuality = 'data_quality', - detections = 'detections', - detectionAndResponse = 'detection_response', - endpoints = 'endpoints', - eventFilters = 'event_filters', - exceptions = 'exceptions', - exploreLanding = 'explore', - hostIsolationExceptions = 'host_isolation_exceptions', - hosts = 'hosts', - hostsAnomalies = 'hosts-anomalies', - hostsRisk = 'hosts-risk', - hostsEvents = 'hosts-events', - investigate = 'investigate', - kubernetes = 'kubernetes', - landing = 'get_started', - network = 'network', - networkAnomalies = 'network-anomalies', - networkDns = 'network-dns', - networkEvents = 'network-events', - networkHttp = 'network-http', - networkTls = 'network-tls', - noPage = '', - overview = 'overview', - policies = 'policy', - responseActionsHistory = 'response_actions_history', - rules = 'rules', - rulesCreate = 'rules-create', - sessions = 'sessions', - /* - * Warning: Computed values are not permitted in an enum with string valued members - * All threat intelligence page names must match `TIPageId` in x-pack/plugins/threat_intelligence/public/common/navigation/types.ts - */ - threatIntelligenceIndicators = 'threat_intelligence-indicators', - timelines = 'timelines', - timelinesTemplates = 'timelines-templates', - trustedApps = 'trusted_apps', - uncommonProcesses = 'uncommon_processes', - users = 'users', - usersAnomalies = 'users-anomalies', - usersAuthentications = 'users-authentications', - usersEvents = 'users-events', - usersRisk = 'users-risk', - entityAnalytics = 'entity-analytics', -} - -export const EXPLORE_PATH = '/explore' as const; -export const DASHBOARDS_PATH = '/dashboards' as const; -export const MANAGE_PATH = '/manage' as const; -export const TIMELINES_PATH = '/timelines' as const; -export const CASES_PATH = '/cases' as const; -export const OVERVIEW_PATH = '/overview' as const; -export const LANDING_PATH = '/get_started' as const; -export const DATA_QUALITY_PATH = '/data_quality' as const; -export const DETECTION_RESPONSE_PATH = '/detection_response' as const; -export const DETECTIONS_PATH = '/detections' as const; -export const ALERTS_PATH = '/alerts' as const; -export const RULES_PATH = '/rules' 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; -export const HOSTS_PATH = '/hosts' as const; -export const USERS_PATH = '/users' as const; -export const KUBERNETES_PATH = '/kubernetes' as const; -export const NETWORK_PATH = '/network' as const; -export const MANAGEMENT_PATH = '/administration' as const; -export const THREAT_INTELLIGENCE_PATH = '/threat_intelligence' as const; -export const ENDPOINTS_PATH = `${MANAGEMENT_PATH}/endpoints` as const; -export const POLICIES_PATH = `${MANAGEMENT_PATH}/policy` as const; -export const TRUSTED_APPS_PATH = `${MANAGEMENT_PATH}/trusted_apps` as const; -export const EVENT_FILTERS_PATH = `${MANAGEMENT_PATH}/event_filters` as const; -export const HOST_ISOLATION_EXCEPTIONS_PATH = - `${MANAGEMENT_PATH}/host_isolation_exceptions` as const; -export const BLOCKLIST_PATH = `${MANAGEMENT_PATH}/blocklist` as const; -export const RESPONSE_ACTIONS_HISTORY_PATH = `${MANAGEMENT_PATH}/response_actions_history` as const; -export const ENTITY_ANALYTICS_PATH = '/entity_analytics' as const; -export const APP_OVERVIEW_PATH = `${APP_PATH}${OVERVIEW_PATH}` as const; -export const APP_LANDING_PATH = `${APP_PATH}${LANDING_PATH}` as const; -export const APP_DETECTION_RESPONSE_PATH = `${APP_PATH}${DETECTION_RESPONSE_PATH}` as const; -export const APP_MANAGEMENT_PATH = `${APP_PATH}${MANAGEMENT_PATH}` as const; - -export const APP_ALERTS_PATH = `${APP_PATH}${ALERTS_PATH}` as const; -export const APP_RULES_PATH = `${APP_PATH}${RULES_PATH}` as const; -export const APP_EXCEPTIONS_PATH = `${APP_PATH}${EXCEPTIONS_PATH}` as const; - -export const APP_HOSTS_PATH = `${APP_PATH}${HOSTS_PATH}` as const; -export const APP_USERS_PATH = `${APP_PATH}${USERS_PATH}` as const; -export const APP_NETWORK_PATH = `${APP_PATH}${NETWORK_PATH}` as const; -export const APP_KUBERNETES_PATH = `${APP_PATH}${KUBERNETES_PATH}` as const; -export const APP_TIMELINES_PATH = `${APP_PATH}${TIMELINES_PATH}` as const; -export const APP_CASES_PATH = `${APP_PATH}${CASES_PATH}` as const; -export const APP_ENDPOINTS_PATH = `${APP_PATH}${ENDPOINTS_PATH}` as const; -export const APP_POLICIES_PATH = `${APP_PATH}${POLICIES_PATH}` as const; -export const APP_TRUSTED_APPS_PATH = `${APP_PATH}${TRUSTED_APPS_PATH}` as const; -export const APP_EVENT_FILTERS_PATH = `${APP_PATH}${EVENT_FILTERS_PATH}` as const; -export const APP_HOST_ISOLATION_EXCEPTIONS_PATH = - `${APP_PATH}${HOST_ISOLATION_EXCEPTIONS_PATH}` as const; -export const APP_BLOCKLIST_PATH = `${APP_PATH}${BLOCKLIST_PATH}` as const; -export const APP_RESPONSE_ACTIONS_HISTORY_PATH = - `${APP_PATH}${RESPONSE_ACTIONS_HISTORY_PATH}` as const; -export const APP_ENTITY_ANALYTICS_PATH = `${APP_PATH}${ENTITY_ANALYTICS_PATH}` as const; -export const APP_DATA_QUALITY_PATH = `${APP_PATH}${DATA_QUALITY_PATH}` as const; - -// cloud logs to exclude from default index pattern -export const EXCLUDE_ELASTIC_CLOUD_INDICES = ['-*elastic-cloud-logs-*']; - -/** The comma-delimited list of Elasticsearch indices from which the SIEM app collects events */ -export const INCLUDE_INDEX_PATTERN = [ - 'apm-*-transaction*', - 'auditbeat-*', - 'endgame-*', - 'filebeat-*', - 'logs-*', - 'packetbeat-*', - 'traces-apm*', - 'winlogbeat-*', -]; -/** The comma-delimited list of Elasticsearch indices from which the SIEM app collects events, and the exclude index pattern */ -export const DEFAULT_INDEX_PATTERN = [...INCLUDE_INDEX_PATTERN, ...EXCLUDE_ELASTIC_CLOUD_INDICES]; - -/** This Kibana Advanced Setting enables the grouped navigation in Security Solution */ -export const ENABLE_GROUPED_NAVIGATION = 'securitySolution:enableGroupedNav' as const; - -/** This Kibana Advanced Setting enables the `Security news` feed widget */ -export const ENABLE_NEWS_FEED_SETTING = 'securitySolution:enableNewsFeed' as const; - -/** This Kibana Advanced Setting enables the warnings for CCS read permissions */ -export const ENABLE_CCS_READ_WARNING_SETTING = 'securitySolution:enableCcsWarning' as const; - -/** This Kibana Advanced Setting sets the auto refresh interval for the detections all rules table */ -export const DEFAULT_RULES_TABLE_REFRESH_SETTING = 'securitySolution:rulesTableRefresh' as const; - -/** This Kibana Advanced Setting specifies the URL of the News feed widget */ -export const NEWS_FEED_URL_SETTING = 'securitySolution:newsFeedUrl' as const; - -/** The default value for News feed widget */ -export const NEWS_FEED_URL_SETTING_DEFAULT = 'https://feeds.elastic.co/security-solution' as const; - -/** This Kibana Advanced Setting specifies the URLs of `IP Reputation Links`*/ -export const IP_REPUTATION_LINKS_SETTING = 'securitySolution:ipReputationLinks' as const; - -/** The default value for `IP Reputation Links` */ -export const IP_REPUTATION_LINKS_SETTING_DEFAULT = `[ - { "name": "virustotal.com", "url_template": "https://www.virustotal.com/gui/search/{{ip}}" }, - { "name": "talosIntelligence.com", "url_template": "https://talosintelligence.com/reputation_center/lookup?search={{ip}}" } -]`; - -/** This Kibana Advanced Setting shows related integrations on the Rules Table */ -export const SHOW_RELATED_INTEGRATIONS_SETTING = - 'securitySolution:showRelatedIntegrations' as const; - -/** This Kibana Advanced Setting enables extended rule execution logging to Event Log */ -export const EXTENDED_RULE_EXECUTION_LOGGING_ENABLED_SETTING = - 'securitySolution:extendedRuleExecutionLoggingEnabled' as const; - -/** This Kibana Advanced Setting sets minimum log level starting from which execution logs will be written to Event Log */ -export const EXTENDED_RULE_EXECUTION_LOGGING_MIN_LEVEL_SETTING = - 'securitySolution:extendedRuleExecutionLoggingMinLevel' as const; - -/** - * Id for the notifications alerting type - * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function - */ -export const LEGACY_NOTIFICATIONS_ID = `siem.notifications` as const; - -/** - * Internal actions route - */ -export const UPDATE_OR_CREATE_LEGACY_ACTIONS = '/internal/api/detection/legacy/notifications'; - -/** - * Exceptions management routes - */ - -export const SHARED_EXCEPTION_LIST_URL = `/api${EXCEPTIONS_PATH}/shared` as const; - -/** - * Detection engine routes - */ -export const DETECTION_ENGINE_URL = '/api/detection_engine' as const; -export const DETECTION_ENGINE_PRIVILEGES_URL = `${DETECTION_ENGINE_URL}/privileges` as const; -export const DETECTION_ENGINE_INDEX_URL = `${DETECTION_ENGINE_URL}/index` as const; - -export const DETECTION_ENGINE_RULES_URL = `${DETECTION_ENGINE_URL}/rules` as const; -export const DETECTION_ENGINE_RULES_URL_FIND = `${DETECTION_ENGINE_RULES_URL}/_find` as const; -export const DETECTION_ENGINE_TAGS_URL = `${DETECTION_ENGINE_URL}/tags` as const; -export const DETECTION_ENGINE_RULES_BULK_ACTION = - `${DETECTION_ENGINE_RULES_URL}/_bulk_action` as const; -export const DETECTION_ENGINE_RULES_PREVIEW = `${DETECTION_ENGINE_RULES_URL}/preview` as const; -export const DETECTION_ENGINE_RULES_BULK_DELETE = - `${DETECTION_ENGINE_RULES_URL}/_bulk_delete` as const; -export const DETECTION_ENGINE_RULES_BULK_CREATE = - `${DETECTION_ENGINE_RULES_URL}/_bulk_create` as const; -export const DETECTION_ENGINE_RULES_BULK_UPDATE = - `${DETECTION_ENGINE_RULES_URL}/_bulk_update` as const; - -export const INTERNAL_RISK_SCORE_URL = '/internal/risk_score' as const; -export const DEV_TOOL_PREBUILT_CONTENT = - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/dev_tool/{console_id}` as const; -export const devToolPrebuiltContentUrl = (spaceId: string, consoleId: string) => - `/s/${spaceId}${INTERNAL_RISK_SCORE_URL}/prebuilt_content/dev_tool/${consoleId}` as const; -export const PREBUILT_SAVED_OBJECTS_BULK_CREATE = `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_create/{template_name}`; -export const prebuiltSavedObjectsBulkCreateUrl = (templateName: string) => - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_create/${templateName}` as const; -export const PREBUILT_SAVED_OBJECTS_BULK_DELETE = `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_delete/{template_name}`; -export const prebuiltSavedObjectsBulkDeleteUrl = (templateName: string) => - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_delete/${templateName}` as const; -export const RISK_SCORE_CREATE_INDEX = `${INTERNAL_RISK_SCORE_URL}/indices/create`; -export const RISK_SCORE_DELETE_INDICES = `${INTERNAL_RISK_SCORE_URL}/indices/delete`; -export const RISK_SCORE_CREATE_STORED_SCRIPT = `${INTERNAL_RISK_SCORE_URL}/stored_scripts/create`; -export const RISK_SCORE_DELETE_STORED_SCRIPT = `${INTERNAL_RISK_SCORE_URL}/stored_scripts/delete`; -/** - * Internal detection engine routes - */ -export const INTERNAL_DETECTION_ENGINE_URL = '/internal/detection_engine' as const; -export const DETECTION_ENGINE_ALERTS_INDEX_URL = - `${INTERNAL_DETECTION_ENGINE_URL}/signal/index` as const; - -/** - * Telemetry detection endpoint for any previews requested of what data we are - * providing through UI/UX and for e2e tests. - * curl http//localhost:5601/internal/security_solution/telemetry - * to see the contents - */ -export const SECURITY_TELEMETRY_URL = `/internal/security_solution/telemetry` as const; - -export const TIMELINE_RESOLVE_URL = '/api/timeline/resolve' as const; -export const TIMELINE_URL = '/api/timeline' as const; -export const TIMELINES_URL = '/api/timelines' as const; -export const TIMELINE_FAVORITE_URL = '/api/timeline/_favorite' as const; -export const TIMELINE_DRAFT_URL = `${TIMELINE_URL}/_draft` as const; -export const TIMELINE_EXPORT_URL = `${TIMELINE_URL}/_export` as const; -export const TIMELINE_IMPORT_URL = `${TIMELINE_URL}/_import` as const; -export const TIMELINE_PREPACKAGED_URL = `${TIMELINE_URL}/_prepackaged` as const; - -export const NOTE_URL = '/api/note' as const; -export const PINNED_EVENT_URL = '/api/pinned_event' as const; -export const SOURCERER_API_URL = '/internal/security_solution/sourcerer' as const; -export const RISK_SCORE_INDEX_STATUS_API_URL = '/internal/risk_score/index_status' as const; - -/** - * Default signals index key for kibana.dev.yml - */ -export const SIGNALS_INDEX_KEY = 'signalsIndex' as const; - -export const DETECTION_ENGINE_SIGNALS_URL = `${DETECTION_ENGINE_URL}/signals` as const; -export const DETECTION_ENGINE_SIGNALS_STATUS_URL = - `${DETECTION_ENGINE_SIGNALS_URL}/status` as const; -export const DETECTION_ENGINE_QUERY_SIGNALS_URL = `${DETECTION_ENGINE_SIGNALS_URL}/search` as const; -export const DETECTION_ENGINE_SIGNALS_MIGRATION_URL = - `${DETECTION_ENGINE_SIGNALS_URL}/migration` as const; -export const DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL = - `${DETECTION_ENGINE_SIGNALS_URL}/migration_status` as const; -export const DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL = - `${DETECTION_ENGINE_SIGNALS_URL}/finalize_migration` as const; - -export const ALERTS_AS_DATA_URL = '/internal/rac/alerts' as const; -export const ALERTS_AS_DATA_FIND_URL = `${ALERTS_AS_DATA_URL}/find` as const; - -/** - * Common naming convention for an unauthenticated user - */ -export const UNAUTHENTICATED_USER = 'Unauthenticated' as const; - -/* - Licensing requirements - */ -export const MINIMUM_ML_LICENSE = 'platinum' as const; - -/* - Machine Learning constants - */ -export const ML_GROUP_ID = 'security' as const; -export const LEGACY_ML_GROUP_ID = 'siem' as const; -export const ML_GROUP_IDS = [ML_GROUP_ID, LEGACY_ML_GROUP_ID] as const; - -export const NOTIFICATION_THROTTLE_NO_ACTIONS = 'no_actions' as const; -export const NOTIFICATION_THROTTLE_RULE = 'rule' as const; - -export const showAllOthersBucket: string[] = [ - 'destination.ip', - 'event.action', - 'event.category', - 'event.dataset', - 'event.module', - 'signal.rule.threat.tactic.name', - 'source.ip', - 'destination.ip', - 'user.name', -]; - -export const RISKY_HOSTS_INDEX_PREFIX = 'ml_host_risk_score_' as const; - -export const RISKY_USERS_INDEX_PREFIX = 'ml_user_risk_score_' as const; - -export const TRANSFORM_STATES = { - ABORTING: 'aborting', - FAILED: 'failed', - INDEXING: 'indexing', - STARTED: 'started', - STOPPED: 'stopped', - STOPPING: 'stopping', - WAITING: 'waiting', -}; - -export const WARNING_TRANSFORM_STATES = new Set([ - TRANSFORM_STATES.ABORTING, - TRANSFORM_STATES.FAILED, - TRANSFORM_STATES.STOPPED, - TRANSFORM_STATES.STOPPING, -]); - -export const STARTED_TRANSFORM_STATES = new Set([ - TRANSFORM_STATES.INDEXING, - TRANSFORM_STATES.STARTED, -]); - -/** - * How many rules to update at a time is set to 50 from errors coming from - * the slow environments such as cloud when the rule updates are > 100 we were - * seeing timeout issues. - * - * Since there is not timeout options at the alerting API level right now, we are - * at the mercy of the Elasticsearch server client/server default timeouts and what - * we are doing could be considered a workaround to not being able to increase the timeouts. - * - * However, other bad effects and saturation of connections beyond 50 makes this a "noisy neighbor" - * if we don't limit its number of connections as we increase the number of rules that can be - * installed at a time. - * - * Lastly, we saw weird issues where Chrome on upstream 408 timeouts will re-call the REST route - * which in turn could create additional connections we want to avoid. - * - * See file import_rules_route.ts for another area where 50 was chosen, therefore I chose - * 50 here to mimic it as well. If you see this re-opened or what similar to it, consider - * reducing the 50 above to a lower number. - * - * See the original ticket here: - * https://github.com/elastic/kibana/issues/94418 - */ -export const MAX_RULES_TO_UPDATE_IN_PARALLEL = 50; - -export const LIMITED_CONCURRENCY_ROUTE_TAG_PREFIX = `${APP_ID}:limitedConcurrency`; - -/** - * Max number of rules to display on UI in table, max number of rules that can be edited in a single bulk edit API request - * We limit number of rules in bulk edit API, because rulesClient doesn't support bulkGet of rules by ids. - * Given this limitation, current implementation fetches each rule separately through rulesClient.resolve method. - * As max number of rules displayed on a page is 100, max 100 rules can be bulk edited by passing their ids to API. - * We decided add this limit(number of ids less than 100) in bulk edit API as well, to prevent a huge number of single rule fetches - */ -export const RULES_TABLE_MAX_PAGE_SIZE = 100; - -/** - * Local storage keys we use to store the state of our new features tours we currently show in the app. - * - * NOTE: As soon as we want to show tours for new features in the upcoming release, - * we will need to update these constants with the corresponding version. - */ -export const NEW_FEATURES_TOUR_STORAGE_KEYS = { - RULE_MANAGEMENT_PAGE: 'securitySolution.rulesManagementPage.newFeaturesTour.v8.6', -}; - -export const RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY = - 'securitySolution.ruleDetails.ruleExecutionLog.showMetrics.v8.2'; - -// TODO: https://github.com/elastic/kibana/pull/142950 -/** - * Error codes that can be thrown during _bulk_action API dry_run call and be processed and displayed to end user - */ -export enum BulkActionsDryRunErrCode { - IMMUTABLE = 'IMMUTABLE', - MACHINE_LEARNING_AUTH = 'MACHINE_LEARNING_AUTH', - MACHINE_LEARNING_INDEX_PATTERN = 'MACHINE_LEARNING_INDEX_PATTERN', -} - -export const RISKY_HOSTS_DOC_LINK = - 'https://www.elastic.co/guide/en/security/current/host-risk-score.html'; -export const RISKY_USERS_DOC_LINK = - 'https://www.elastic.co/guide/en/security/current/user-risk-score.html'; - -export const MAX_NUMBER_OF_NEW_TERMS_FIELDS = 3; - -export const BULK_ADD_TO_TIMELINE_LIMIT = 2000; - -export const DEFAULT_DETECTION_PAGE_FILTERS = [ - { - title: 'Status', - fieldName: 'kibana.alert.workflow_status', - selectedOptions: ['open'], - hideActionBar: true, - }, - { - title: 'Severity', - fieldName: 'kibana.alert.severity', - selectedOptions: [], - hideActionBar: true, - }, - { - title: 'User', - fieldName: 'user.name', - }, - { - title: 'Host', - fieldName: 'host.name', - }, -]; diff --git a/x-pack/packages/security-solution/data_table/mock/mock_source.ts b/x-pack/packages/security-solution/data_table/mock/mock_source.ts index 0cc791f288410..82c2a34448153 100644 --- a/x-pack/packages/security-solution/data_table/mock/mock_source.ts +++ b/x-pack/packages/security-solution/data_table/mock/mock_source.ts @@ -7,7 +7,18 @@ import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { BrowserFields } from '@kbn/timelines-plugin/common'; -import { DEFAULT_INDEX_PATTERN } from '../common/constants'; + +const DEFAULT_INDEX_PATTERN = [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'traces-apm*', + 'winlogbeat-*', + '-*elastic-cloud-logs-*', +]; export const mockBrowserFields: BrowserFields = { agent: { diff --git a/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.test.ts b/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.test.ts index f6cfe42d0583a..8e96e14a29f2b 100644 --- a/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.test.ts +++ b/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.test.ts @@ -6,7 +6,7 @@ */ import { cloudDefendPages } from './constants'; -import { getSecuritySolutionLink, getSecuritySolutionNavTab } from './security_solution_links'; +import { getSecuritySolutionLink } from './security_solution_links'; import { Chance } from 'chance'; import type { CloudDefendPage } from './types'; @@ -23,17 +23,3 @@ describe('getSecuritySolutionLink', () => { expect(link.title).toEqual(cloudDefendPages[cloudDefendPage].name); }); }); - -describe('getSecuritySolutionNavTab', () => { - it('gets the correct nav tab properties', () => { - const cloudDefendPage = chance.pickone(['policies']); - const basePath = chance.word(); - - const navTab = getSecuritySolutionNavTab(cloudDefendPage, basePath); - - expect(navTab.id).toEqual(cloudDefendPages[cloudDefendPage].id); - expect(navTab.name).toEqual(cloudDefendPages[cloudDefendPage].name); - expect(navTab.href).toEqual(`${basePath}${cloudDefendPages[cloudDefendPage].path}`); - expect(navTab.disabled).toEqual(!!cloudDefendPages[cloudDefendPage].disabled); - }); -}); diff --git a/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.ts b/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.ts index 58e816c135593..4f9ad57c1d94b 100644 --- a/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.ts +++ b/x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.ts @@ -14,13 +14,6 @@ interface CloudDefendLinkItem { path: string; } -interface CloudDefendNavTab { - id: TId; - name: string; - href: string; - disabled: boolean; -} - /** * Gets the cloud_defend link properties of a Cloud Defend page for navigation in the security solution. * @param cloudDefendPage the name of the cloud defend page. @@ -34,18 +27,3 @@ export const getSecuritySolutionLink = ( path: cloudDefendPages[cloudDefendPage].path, }; }; - -/** - * Gets the link properties of a Cloud Defend page for navigation in the old security solution navigation. - * @param cloudDefendPage the name of the cloud defend page. - * @param basePath the base path for links. - */ -export const getSecuritySolutionNavTab = ( - cloudDefendPage: CloudDefendPage, - basePath: string -): CloudDefendNavTab => ({ - id: cloudDefendPages[cloudDefendPage].id as TId, - name: cloudDefendPages[cloudDefendPage].name, - href: `${basePath}${cloudDefendPages[cloudDefendPage].path}`, - disabled: !!cloudDefendPages[cloudDefendPage].disabled, -}); diff --git a/x-pack/plugins/cloud_defend/public/index.ts b/x-pack/plugins/cloud_defend/public/index.ts index b74c04111c91b..9dcf8bd5b2760 100755 --- a/x-pack/plugins/cloud_defend/public/index.ts +++ b/x-pack/plugins/cloud_defend/public/index.ts @@ -7,10 +7,7 @@ import { CloudDefendPlugin } from './plugin'; export type { CloudDefendSecuritySolutionContext } from './types'; -export { - getSecuritySolutionLink, - getSecuritySolutionNavTab, -} from './common/navigation/security_solution_links'; +export { getSecuritySolutionLink } from './common/navigation/security_solution_links'; export { CLOUD_DEFEND_BASE_PATH } from './common/navigation/constants'; export type { CloudDefendPageId } from './common/navigation/types'; diff --git a/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.test.ts b/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.test.ts index ae542ba885ec9..e36b8a185d429 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.test.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.test.ts @@ -6,7 +6,7 @@ */ import { cloudPosturePages } from './constants'; -import { getSecuritySolutionLink, getSecuritySolutionNavTab } from './security_solution_links'; +import { getSecuritySolutionLink } from './security_solution_links'; import { Chance } from 'chance'; import type { CspPage } from './types'; @@ -28,22 +28,3 @@ describe('getSecuritySolutionLink', () => { expect(link.title).toEqual(cloudPosturePages[cspPage].name); }); }); - -describe('getSecuritySolutionNavTab', () => { - it('gets the correct nav tab properties', () => { - const cspPage = chance.pickone([ - 'dashboard', - 'findings', - 'benchmarks', - 'vulnerability_dashboard', - ]); - const basePath = chance.word(); - - const navTab = getSecuritySolutionNavTab(cspPage, basePath); - - expect(navTab.id).toEqual(cloudPosturePages[cspPage].id); - expect(navTab.name).toEqual(cloudPosturePages[cspPage].name); - expect(navTab.href).toEqual(`${basePath}${cloudPosturePages[cspPage].path}`); - expect(navTab.disabled).toEqual(!!cloudPosturePages[cspPage].disabled); - }); -}); diff --git a/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.ts b/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.ts index 9942c95f08094..da21c4cf63090 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.ts @@ -14,13 +14,6 @@ interface CloudSecurityPostureLinkItem { - id: TId; - name: string; - href: string; - disabled: boolean; -} - /** * Gets the cloud security posture link properties of a CSP page for navigation in the security solution. * @param cloudSecurityPosturePage the name of the cloud posture page. @@ -32,18 +25,3 @@ export const getSecuritySolutionLink = ( - cloudSecurityPosturePage: CspPage, - basePath: string -): CloudSecurityPostureNavTab => ({ - id: cloudPosturePages[cloudSecurityPosturePage].id as TId, - name: cloudPosturePages[cloudSecurityPosturePage].name, - href: `${basePath}${cloudPosturePages[cloudSecurityPosturePage].path}`, - disabled: !!cloudPosturePages[cloudSecurityPosturePage].disabled, -}); diff --git a/x-pack/plugins/cloud_security_posture/public/index.ts b/x-pack/plugins/cloud_security_posture/public/index.ts index 532a30524845d..64301add72ca3 100755 --- a/x-pack/plugins/cloud_security_posture/public/index.ts +++ b/x-pack/plugins/cloud_security_posture/public/index.ts @@ -9,10 +9,7 @@ import { CspPlugin } from './plugin'; export type { CspSecuritySolutionContext } from './types'; export { CLOUD_SECURITY_POSTURE_BASE_PATH } from './common/navigation/constants'; export type { CloudSecurityPosturePageId } from './common/navigation/types'; -export { - getSecuritySolutionLink, - getSecuritySolutionNavTab, -} from './common/navigation/security_solution_links'; +export { getSecuritySolutionLink } from './common/navigation/security_solution_links'; export type { CspClientPluginSetup, CspClientPluginStart } from './types'; diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 7da50bd569a47..34694ea652caf 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -220,9 +220,6 @@ export const INCLUDE_INDEX_PATTERN = [ /** The comma-delimited list of Elasticsearch indices from which the SIEM app collects events, and the exclude index pattern */ export const DEFAULT_INDEX_PATTERN = [...INCLUDE_INDEX_PATTERN, ...EXCLUDE_ELASTIC_CLOUD_INDICES]; -/** This Kibana Advanced Setting enables the grouped navigation in Security Solution */ -export const ENABLE_GROUPED_NAVIGATION = 'securitySolution:enableGroupedNav' as const; - /** This Kibana Advanced Setting enables the `Security news` feed widget */ export const ENABLE_NEWS_FEED_SETTING = 'securitySolution:enableNewsFeed' as const; diff --git a/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts b/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts deleted file mode 100644 index 8b6db14e78986..0000000000000 --- a/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts +++ /dev/null @@ -1,195 +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 { getDeepLinks, hasFeaturesCapability } from '.'; -import type { AppDeepLink, Capabilities } from '@kbn/core/public'; -import { SecurityPageName } from '../types'; -import { mockGlobalState } from '../../common/mock'; -import { CASES_FEATURE_ID, SERVER_APP_ID } from '../../../common/constants'; -import { createCapabilities } from '../../common/links/test_utils'; - -const findDeepLink = (id: string, deepLinks: AppDeepLink[]): AppDeepLink | null => - deepLinks.reduce((deepLinkFound: AppDeepLink | null, deepLink) => { - if (deepLinkFound !== null) { - return deepLinkFound; - } - if (deepLink.id === id) { - return deepLink; - } - if (deepLink.deepLinks) { - return findDeepLink(id, deepLink.deepLinks); - } - return null; - }, null); - -const basicLicense = 'basic'; -const platinumLicense = 'platinum'; - -describe('deepLinks', () => { - describe('hasFeaturesCapability', () => { - it('returns true when features is undefined', () => { - expect( - hasFeaturesCapability(undefined, createCapabilities({ siem: { show: true } })) - ).toBeTruthy(); - }); - }); - - it('should return a all basic license deep links in the premium deep links', () => { - const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense); - const platinumLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense); - - const testAllBasicInPlatinum = ( - basicDeepLinks: AppDeepLink[], - platinumDeepLinks: AppDeepLink[] - ) => { - basicDeepLinks.forEach((basicDeepLink) => { - const platinumDeepLink = platinumDeepLinks.find(({ id }) => id === basicDeepLink.id); - expect(platinumDeepLink).toBeTruthy(); - - if (platinumDeepLink && basicDeepLink.deepLinks) { - expect(platinumDeepLink.deepLinks).toBeTruthy(); - - if (platinumDeepLink.deepLinks) { - testAllBasicInPlatinum(basicDeepLink.deepLinks, platinumDeepLink.deepLinks); - } - } - }); - }; - testAllBasicInPlatinum(basicLinks, platinumLinks); - }); - - it('should not return premium deep links in basic license deep links', () => { - const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense); - const platinumLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense); - - [ - SecurityPageName.hostsAnomalies, - SecurityPageName.networkAnomalies, - SecurityPageName.caseConfigure, - ].forEach((premiumDeepLinkId) => { - expect(findDeepLink(premiumDeepLinkId, platinumLinks)).toBeTruthy(); - expect(findDeepLink(premiumDeepLinkId, basicLinks)).toBeFalsy(); - }); - }); - - it('should return case links for basic license with only read_cases capabilities', () => { - const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - [CASES_FEATURE_ID]: { read_cases: true }, - [SERVER_APP_ID]: { show: true }, - } as unknown as Capabilities); - expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy(); - }); - - it('should return case links with NO deepLinks for basic license with only read_cases capabilities', () => { - const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - [CASES_FEATURE_ID]: { read_cases: true }, - [SERVER_APP_ID]: { show: true }, - } as unknown as Capabilities); - expect(findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length === 0).toBeTruthy(); - }); - - it('should return case links with deepLinks for basic license with permissive capabilities', () => { - const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - [CASES_FEATURE_ID]: { - create_cases: true, - read_cases: true, - update_cases: true, - delete_cases: true, - push_cases: true, - }, - [SERVER_APP_ID]: { show: true }, - } as unknown as Capabilities); - - expect( - (findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length ?? 0) > 0 - ).toBeTruthy(); - }); - - it('should return case links with deepLinks for basic license with permissive capabilities and security disabled', () => { - const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense, { - [CASES_FEATURE_ID]: { - create_cases: true, - read_cases: true, - update_cases: true, - delete_cases: true, - push_cases: true, - }, - [SERVER_APP_ID]: { show: false }, - } as unknown as Capabilities); - expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy(); - }); - - it('should return NO case links for basic license with NO cases capabilities', () => { - const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - [CASES_FEATURE_ID]: { - create_cases: false, - read_cases: false, - update_cases: false, - delete_cases: false, - push_cases: false, - }, - [SERVER_APP_ID]: { show: true }, - } as unknown as Capabilities); - expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeFalsy(); - }); - - it('should return empty links for any license', () => { - const emptyDeepLinks = getDeepLinks( - mockGlobalState.app.enableExperimental, - basicLicense, - {} as unknown as Capabilities - ); - expect(emptyDeepLinks.length).toBe(0); - }); - - it('should return case links for basic license with undefined capabilities', () => { - const basicLinks = getDeepLinks( - mockGlobalState.app.enableExperimental, - basicLicense, - undefined - ); - - expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy(); - }); - - it('should return case deepLinks for basic license with undefined capabilities', () => { - const basicLinks = getDeepLinks( - mockGlobalState.app.enableExperimental, - basicLicense, - undefined - ); - - expect( - (findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length ?? 0) > 0 - ).toBeTruthy(); - }); - - it('should return users link', () => { - const deepLinks = getDeepLinks({ - ...mockGlobalState.app.enableExperimental, - }); - expect(findDeepLink(SecurityPageName.users, deepLinks)).toBeTruthy(); - }); - - describe('experimental flags', () => { - it('should return NO kubernetes link when enableExperimental.kubernetesEnabled === false', () => { - const deepLinks = getDeepLinks({ - ...mockGlobalState.app.enableExperimental, - kubernetesEnabled: false, - }); - - expect(findDeepLink(SecurityPageName.kubernetes, deepLinks)).toBeFalsy(); - }); - - it('should return kubernetes link when enableExperimental.kubernetesEnabled === true', () => { - const deepLinks = getDeepLinks({ - ...mockGlobalState.app.enableExperimental, - kubernetesEnabled: true, - }); - expect(findDeepLink(SecurityPageName.kubernetes, deepLinks)).toBeTruthy(); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/app/deep_links/index.ts b/x-pack/plugins/security_solution/public/app/deep_links/index.ts deleted file mode 100644 index e0bd41655545c..0000000000000 --- a/x-pack/plugins/security_solution/public/app/deep_links/index.ts +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -import { getSecuritySolutionLink as getCloudDefendSecuritySolutionLink } from '@kbn/cloud-defend-plugin/public'; -import { getSecuritySolutionLink as getCloudPostureSecuritySolutionLink } from '@kbn/cloud-security-posture-plugin/public'; -import { getSecuritySolutionDeepLink } from '@kbn/threat-intelligence-plugin/public'; -import type { LicenseType } from '@kbn/licensing-plugin/common/types'; -import { getCasesDeepLinks } from '@kbn/cases-plugin/public'; -import { - CREATE_CASES_CAPABILITY, - DELETE_CASES_CAPABILITY, - PUSH_CASES_CAPABILITY, - READ_CASES_CAPABILITY, - UPDATE_CASES_CAPABILITY, -} from '@kbn/cases-plugin/common'; -import type { AppDeepLink, AppUpdater, Capabilities } from '@kbn/core/public'; -import { AppNavLinkStatus } from '@kbn/core/public'; -import type { Subject, Subscription } from 'rxjs'; -import { SecurityPageName } from '../types'; -import { - ALERTS, - BLOCKLIST, - CREATE_NEW_RULE, - DASHBOARDS, - DATA_QUALITY, - DETECT, - DETECTION_RESPONSE, - ENDPOINTS, - EVENT_FILTERS, - EXCEPTIONS, - EXPLORE, - GETTING_STARTED, - HOST_ISOLATION_EXCEPTIONS, - HOSTS, - INVESTIGATE, - KUBERNETES, - MANAGE, - NETWORK, - OVERVIEW, - POLICIES, - RESPONSE_ACTIONS_HISTORY, - ENTITY_ANALYTICS, - RULES, - TIMELINES, - TRUSTED_APPLICATIONS, - USERS, -} from '../translations'; -import { - ALERTS_PATH, - BLOCKLIST_PATH, - CASES_FEATURE_ID, - CASES_PATH, - DATA_QUALITY_PATH, - DETECTION_RESPONSE_PATH, - ENDPOINTS_PATH, - EVENT_FILTERS_PATH, - EXCEPTIONS_PATH, - HOST_ISOLATION_EXCEPTIONS_PATH, - HOSTS_PATH, - KUBERNETES_PATH, - LANDING_PATH, - NETWORK_PATH, - OVERVIEW_PATH, - POLICIES_PATH, - RESPONSE_ACTIONS_HISTORY_PATH, - ENTITY_ANALYTICS_PATH, - RULES_CREATE_PATH, - RULES_PATH, - SERVER_APP_ID, - TIMELINES_PATH, - TRUSTED_APPS_PATH, - USERS_PATH, -} from '../../../common/constants'; -import type { ExperimentalFeatures } from '../../../common/experimental_features'; -import { appLinks$, hasCapabilities } from '../../common/links'; -import type { AppLinkItems } from '../../common/links/types'; - -export const FEATURE = { - general: `${SERVER_APP_ID}.show`, - casesCreate: `${CASES_FEATURE_ID}.${CREATE_CASES_CAPABILITY}`, - casesRead: `${CASES_FEATURE_ID}.${READ_CASES_CAPABILITY}`, - casesUpdate: `${CASES_FEATURE_ID}.${UPDATE_CASES_CAPABILITY}`, - casesDelete: `${CASES_FEATURE_ID}.${DELETE_CASES_CAPABILITY}`, - casesPush: `${CASES_FEATURE_ID}.${PUSH_CASES_CAPABILITY}`, -} as const; - -type FeatureKey = typeof FEATURE[keyof typeof FEATURE]; - -/** - * The format of defining features supports OR and AND mechanism. To specify features in an OR fashion - * they can be defined in a single level array like: [requiredFeature1, requiredFeature2]. If either of these features - * is satisfied the deeplinks would be included. To require that the features be AND'd together a second level array - * can be specified: [feature1, [feature2, feature3]] this would result in feature1 || (feature2 && feature3). To specify - * features that all must be and'd together an example would be: [[feature1, feature2]], this would result in the boolean - * operation feature1 && feature2. - * - * The final format is to specify a single feature, this would be like: features: feature1, which is the same as - * features: [feature1] - */ -type Features = FeatureKey | Array; - -type SecuritySolutionDeepLink = AppDeepLink & { - isPremium?: boolean; - features?: Features; - /** - * Displays deep link when feature flag is enabled. - */ - experimentalKey?: keyof ExperimentalFeatures; - /** - * Hides deep link when feature flag is enabled. - */ - hideWhenExperimentalKey?: keyof ExperimentalFeatures; - deepLinks?: SecuritySolutionDeepLink[]; -}; - -export const securitySolutionsDeepLinks: SecuritySolutionDeepLink[] = [ - { - id: SecurityPageName.landing, - title: GETTING_STARTED, - path: LANDING_PATH, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.getStarted', { - defaultMessage: 'Getting started', - }), - ], - }, - { - id: SecurityPageName.dashboards, - title: DASHBOARDS, - path: OVERVIEW_PATH, - navLinkStatus: AppNavLinkStatus.visible, - searchable: false, - order: 9000, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.dashboards', { - defaultMessage: 'Dashboards', - }), - ], - deepLinks: [ - { - id: SecurityPageName.overview, - title: OVERVIEW, - path: OVERVIEW_PATH, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.overview', { - defaultMessage: 'Overview', - }), - ], - }, - { - id: SecurityPageName.detectionAndResponse, - title: DETECTION_RESPONSE, - path: DETECTION_RESPONSE_PATH, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.detectionAndResponse', { - defaultMessage: 'Detection & Response', - }), - ], - }, - { - ...getCloudPostureSecuritySolutionLink('dashboard'), - features: [FEATURE.general], - }, - { - id: SecurityPageName.entityAnalytics, - title: ENTITY_ANALYTICS, - path: ENTITY_ANALYTICS_PATH, - features: [FEATURE.general], - isPremium: true, - keywords: [ - i18n.translate('xpack.securitySolution.search.entityAnalytics', { - defaultMessage: 'Entity Analytics', - }), - ], - }, - { - id: SecurityPageName.dataQuality, - title: DATA_QUALITY, - path: DATA_QUALITY_PATH, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.dataQualityDashboard', { - defaultMessage: 'Data quality', - }), - ], - }, - ], - }, - { - id: SecurityPageName.detections, - title: DETECT, - path: ALERTS_PATH, - navLinkStatus: AppNavLinkStatus.hidden, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.detect', { - defaultMessage: 'Detect', - }), - ], - deepLinks: [ - { - id: SecurityPageName.alerts, - title: ALERTS, - path: ALERTS_PATH, - navLinkStatus: AppNavLinkStatus.visible, - order: 9001, - keywords: [ - i18n.translate('xpack.securitySolution.search.alerts', { - defaultMessage: 'Alerts', - }), - ], - }, - { - id: SecurityPageName.rules, - title: RULES, - path: RULES_PATH, - keywords: [ - i18n.translate('xpack.securitySolution.search.rules', { - defaultMessage: 'Rules', - }), - ], - deepLinks: [ - { - id: SecurityPageName.rulesCreate, - title: CREATE_NEW_RULE, - path: RULES_CREATE_PATH, - navLinkStatus: AppNavLinkStatus.hidden, - searchable: false, - }, - ], - }, - { - id: SecurityPageName.exceptions, - title: EXCEPTIONS, - path: EXCEPTIONS_PATH, - keywords: [ - i18n.translate('xpack.securitySolution.search.exceptions', { - defaultMessage: 'Exception lists', - }), - ], - }, - ], - }, - { - ...getCloudPostureSecuritySolutionLink('findings'), - features: [FEATURE.general], - navLinkStatus: AppNavLinkStatus.visible, - order: 9002, - }, - { - id: SecurityPageName.exploreLanding, - title: EXPLORE, - path: HOSTS_PATH, - navLinkStatus: AppNavLinkStatus.visible, - order: 9005, - searchable: false, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.explore', { - defaultMessage: 'Explore', - }), - ], - deepLinks: [ - { - id: SecurityPageName.hosts, - title: HOSTS, - path: HOSTS_PATH, - keywords: [ - i18n.translate('xpack.securitySolution.search.hosts', { - defaultMessage: 'Hosts', - }), - ], - deepLinks: [ - { - id: SecurityPageName.uncommonProcesses, - title: i18n.translate('xpack.securitySolution.search.hosts.uncommonProcesses', { - defaultMessage: 'Uncommon Processes', - }), - path: `${HOSTS_PATH}/uncommonProcesses`, - }, - { - id: SecurityPageName.hostsAnomalies, - title: i18n.translate('xpack.securitySolution.search.hosts.anomalies', { - defaultMessage: 'Anomalies', - }), - path: `${HOSTS_PATH}/anomalies`, - isPremium: true, - }, - { - id: SecurityPageName.hostsEvents, - title: i18n.translate('xpack.securitySolution.search.hosts.events', { - defaultMessage: 'Events', - }), - path: `${HOSTS_PATH}/events`, - }, - { - id: SecurityPageName.hostsRisk, - title: i18n.translate('xpack.securitySolution.search.hosts.risk', { - defaultMessage: 'Host risk', - }), - path: `${HOSTS_PATH}/hostRisk`, - }, - { - id: SecurityPageName.sessions, - title: i18n.translate('xpack.securitySolution.search.hosts.sessions', { - defaultMessage: 'Sessions', - }), - path: `${HOSTS_PATH}/sessions`, - }, - ], - }, - { - id: SecurityPageName.network, - title: NETWORK, - path: NETWORK_PATH, - keywords: [ - i18n.translate('xpack.securitySolution.search.network', { - defaultMessage: 'Network', - }), - ], - deepLinks: [ - { - id: SecurityPageName.networkDns, - title: i18n.translate('xpack.securitySolution.search.network.dns', { - defaultMessage: 'DNS', - }), - path: `${NETWORK_PATH}/dns`, - }, - { - id: SecurityPageName.networkHttp, - title: i18n.translate('xpack.securitySolution.search.network.http', { - defaultMessage: 'HTTP', - }), - path: `${NETWORK_PATH}/http`, - }, - { - id: SecurityPageName.networkTls, - title: i18n.translate('xpack.securitySolution.search.network.tls', { - defaultMessage: 'TLS', - }), - path: `${NETWORK_PATH}/tls`, - }, - { - id: SecurityPageName.networkAnomalies, - title: i18n.translate('xpack.securitySolution.search.network.anomalies', { - defaultMessage: 'Anomalies', - }), - path: `${NETWORK_PATH}/anomalies`, - isPremium: true, - }, - { - id: SecurityPageName.networkEvents, - title: i18n.translate('xpack.securitySolution.search.network.events', { - defaultMessage: 'Events', - }), - path: `${NETWORK_PATH}/events`, - }, - ], - }, - { - id: SecurityPageName.users, - title: USERS, - path: USERS_PATH, - keywords: [ - i18n.translate('xpack.securitySolution.search.users', { - defaultMessage: 'Users', - }), - ], - deepLinks: [ - { - id: SecurityPageName.usersAuthentications, - title: i18n.translate('xpack.securitySolution.search.users.authentications', { - defaultMessage: 'Authentications', - }), - path: `${USERS_PATH}/authentications`, - }, - { - id: SecurityPageName.usersAnomalies, - title: i18n.translate('xpack.securitySolution.search.users.anomalies', { - defaultMessage: 'Anomalies', - }), - path: `${USERS_PATH}/anomalies`, - isPremium: true, - }, - { - id: SecurityPageName.usersRisk, - title: i18n.translate('xpack.securitySolution.search.users.risk', { - defaultMessage: 'User risk', - }), - path: `${USERS_PATH}/userRisk`, - }, - { - id: SecurityPageName.usersEvents, - title: i18n.translate('xpack.securitySolution.search.users.events', { - defaultMessage: 'Events', - }), - path: `${USERS_PATH}/events`, - }, - ], - }, - { - ...getSecuritySolutionDeepLink('indicators'), - navLinkStatus: AppNavLinkStatus.visible, - order: 9006, - features: [FEATURE.general], - }, - { - id: SecurityPageName.kubernetes, - title: KUBERNETES, - path: KUBERNETES_PATH, - experimentalKey: 'kubernetesEnabled', - keywords: [ - i18n.translate('xpack.securitySolution.search.kubernetes', { - defaultMessage: 'Kubernetes', - }), - ], - }, - ], - }, - { - id: SecurityPageName.investigate, - title: INVESTIGATE, - navLinkStatus: AppNavLinkStatus.hidden, - features: [FEATURE.general, FEATURE.casesRead], - keywords: [ - i18n.translate('xpack.securitySolution.search.investigate', { - defaultMessage: 'Investigate', - }), - ], - deepLinks: [ - { - id: SecurityPageName.timelines, - title: TIMELINES, - path: TIMELINES_PATH, - navLinkStatus: AppNavLinkStatus.visible, - order: 9003, - features: [FEATURE.general], - keywords: [ - i18n.translate('xpack.securitySolution.search.timelines', { - defaultMessage: 'Timelines', - }), - ], - deepLinks: [ - { - id: SecurityPageName.timelinesTemplates, - title: i18n.translate('xpack.securitySolution.search.timeline.templates', { - defaultMessage: 'Templates', - }), - path: `${TIMELINES_PATH}/template`, - }, - ], - }, - getCasesDeepLinks({ - basePath: CASES_PATH, - extend: { - [SecurityPageName.case]: { - navLinkStatus: AppNavLinkStatus.visible, - order: 9004, - features: [FEATURE.casesRead], - }, - [SecurityPageName.caseConfigure]: { - features: [FEATURE.casesUpdate], - isPremium: true, - }, - [SecurityPageName.caseCreate]: { - features: [FEATURE.casesCreate], - }, - }, - }), - ], - }, - { - id: SecurityPageName.administration, - title: MANAGE, - path: ENDPOINTS_PATH, - features: [FEATURE.general], - navLinkStatus: AppNavLinkStatus.visible, - order: 9007, - searchable: false, - keywords: [ - i18n.translate('xpack.securitySolution.search.manage', { - defaultMessage: 'Manage', - }), - ], - deepLinks: [ - { - id: SecurityPageName.endpoints, - title: ENDPOINTS, - path: ENDPOINTS_PATH, - }, - { - id: SecurityPageName.policies, - title: POLICIES, - path: POLICIES_PATH, - experimentalKey: 'policyListEnabled', - }, - { - id: SecurityPageName.trustedApps, - title: TRUSTED_APPLICATIONS, - path: TRUSTED_APPS_PATH, - }, - { - id: SecurityPageName.eventFilters, - title: EVENT_FILTERS, - path: EVENT_FILTERS_PATH, - }, - { - id: SecurityPageName.hostIsolationExceptions, - title: HOST_ISOLATION_EXCEPTIONS, - path: HOST_ISOLATION_EXCEPTIONS_PATH, - }, - { - id: SecurityPageName.blocklist, - title: BLOCKLIST, - path: BLOCKLIST_PATH, - }, - { - id: SecurityPageName.responseActionsHistory, - title: RESPONSE_ACTIONS_HISTORY, - path: RESPONSE_ACTIONS_HISTORY_PATH, - }, - { - ...getCloudPostureSecuritySolutionLink('benchmarks'), - }, - { - ...getCloudDefendSecuritySolutionLink('policies'), - }, - ], - }, -]; - -/** - * A function that generates the plugin deepLinks structure - * used by Kibana to build the global side navigation and application search results - * @param enableExperimental ExperimentalFeatures arg - * @param licenseType optional string for license level, if not provided basic is assumed. - * @param capabilities optional arg for app start capabilities - */ -export function getDeepLinks( - enableExperimental: ExperimentalFeatures, - licenseType?: LicenseType, - capabilities?: Capabilities -): AppDeepLink[] { - const filterDeepLinks = (securityDeepLinks: SecuritySolutionDeepLink[]): AppDeepLink[] => - securityDeepLinks.reduce( - ( - deepLinks: AppDeepLink[], - { isPremium, features, experimentalKey, hideWhenExperimentalKey, ...deepLink } - ) => { - if (licenseType && isPremium && !isPremiumLicense(licenseType)) { - return deepLinks; - } - if (experimentalKey && !enableExperimental[experimentalKey]) { - return deepLinks; - } - - if (hideWhenExperimentalKey && enableExperimental[hideWhenExperimentalKey]) { - return deepLinks; - } - - if (capabilities != null && !hasFeaturesCapability(features, capabilities)) { - return deepLinks; - } - if (deepLink.deepLinks) { - deepLinks.push({ ...deepLink, deepLinks: filterDeepLinks(deepLink.deepLinks) }); - } else { - deepLinks.push(deepLink); - } - return deepLinks; - }, - [] - ); - return filterDeepLinks(securitySolutionsDeepLinks); -} - -export function hasFeaturesCapability( - features: Features | undefined, - capabilities: Capabilities -): boolean { - if (!features) { - return true; - } - - return hasCapabilities(features, capabilities); -} - -export function isPremiumLicense(licenseType?: LicenseType): boolean { - return ( - licenseType === 'gold' || - licenseType === 'platinum' || - licenseType === 'enterprise' || - licenseType === 'trial' - ); -} - -/** - * New deep links code starts here. - * All the code above will be removed once the appLinks migration is over. - * The code below manages the new implementation using the unified appLinks. - */ - -const formatDeepLinks = (appLinks: AppLinkItems): AppDeepLink[] => - appLinks.map((appLink) => ({ - id: appLink.id, - path: appLink.path, - title: appLink.title, - searchable: !appLink.globalSearchDisabled, - ...(appLink.globalNavPosition != null - ? { navLinkStatus: AppNavLinkStatus.visible, order: appLink.globalNavPosition } - : { navLinkStatus: AppNavLinkStatus.hidden }), - ...(appLink.globalSearchKeywords != null ? { keywords: appLink.globalSearchKeywords } : {}), - ...(appLink.links && appLink.links?.length - ? { - deepLinks: formatDeepLinks(appLink.links), - } - : {}), - })); - -/** - * Registers any change in appLinks to be updated in app deepLinks - */ -export const registerDeepLinksUpdater = (appUpdater$: Subject): Subscription => { - return appLinks$.subscribe((appLinks) => { - appUpdater$.next(() => ({ - navLinkStatus: AppNavLinkStatus.hidden, // needed to prevent main security link to switch to visible after update - deepLinks: formatDeepLinks(appLinks), - })); - }); -}; diff --git a/x-pack/plugins/security_solution/public/app/home/home_navigations.ts b/x-pack/plugins/security_solution/public/app/home/home_navigations.ts deleted file mode 100644 index d9a988004ac1a..0000000000000 --- a/x-pack/plugins/security_solution/public/app/home/home_navigations.ts +++ /dev/null @@ -1,239 +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 { getSecuritySolutionNavTab as getSecuritySolutionCSPNavTab } from '@kbn/cloud-security-posture-plugin/public'; -import { getSecuritySolutionNavTab as getSecuritySolutionTINavTab } from '@kbn/threat-intelligence-plugin/public'; -import { getSecuritySolutionNavTab as getSecuritySolutionCloudDefendNavTab } from '@kbn/cloud-defend-plugin/public'; -import * as i18n from '../translations'; -import type { SecurityNav, SecurityNavGroup } from '../../common/components/navigation/types'; -import { SecurityNavGroupKey } from '../../common/components/navigation/types'; -import { - APP_OVERVIEW_PATH, - APP_DETECTION_RESPONSE_PATH, - APP_RULES_PATH, - APP_ALERTS_PATH, - APP_EXCEPTIONS_PATH, - APP_HOSTS_PATH, - APP_NETWORK_PATH, - APP_TIMELINES_PATH, - APP_CASES_PATH, - APP_ENDPOINTS_PATH, - APP_POLICIES_PATH, - APP_TRUSTED_APPS_PATH, - APP_EVENT_FILTERS_PATH, - APP_BLOCKLIST_PATH, - SecurityPageName, - APP_HOST_ISOLATION_EXCEPTIONS_PATH, - APP_USERS_PATH, - APP_KUBERNETES_PATH, - APP_LANDING_PATH, - APP_RESPONSE_ACTIONS_HISTORY_PATH, - APP_ENTITY_ANALYTICS_PATH, - APP_DATA_QUALITY_PATH, - APP_PATH, -} from '../../../common/constants'; - -export const navTabs: SecurityNav = { - [SecurityPageName.landing]: { - id: SecurityPageName.landing, - name: i18n.GETTING_STARTED, - href: APP_LANDING_PATH, - disabled: false, - urlKey: 'get_started', - }, - [SecurityPageName.overview]: { - id: SecurityPageName.overview, - name: i18n.OVERVIEW, - href: APP_OVERVIEW_PATH, - disabled: false, - urlKey: 'overview', - }, - [SecurityPageName.detectionAndResponse]: { - id: SecurityPageName.detectionAndResponse, - name: i18n.DETECTION_RESPONSE, - href: APP_DETECTION_RESPONSE_PATH, - disabled: false, - urlKey: 'detection_response', - }, - [SecurityPageName.alerts]: { - id: SecurityPageName.alerts, - name: i18n.ALERTS, - href: APP_ALERTS_PATH, - disabled: false, - urlKey: 'alerts', - }, - [SecurityPageName.rules]: { - id: SecurityPageName.rules, - name: i18n.RULES, - href: APP_RULES_PATH, - disabled: false, - urlKey: 'rules', - }, - [SecurityPageName.exceptions]: { - id: SecurityPageName.exceptions, - name: i18n.EXCEPTIONS, - href: APP_EXCEPTIONS_PATH, - disabled: false, - urlKey: 'exceptions', - }, - [SecurityPageName.hosts]: { - id: SecurityPageName.hosts, - name: i18n.HOSTS, - href: APP_HOSTS_PATH, - disabled: false, - urlKey: 'host', - }, - [SecurityPageName.users]: { - id: SecurityPageName.users, - name: i18n.USERS, - href: APP_USERS_PATH, - disabled: false, - urlKey: 'users', - }, - [SecurityPageName.network]: { - id: SecurityPageName.network, - name: i18n.NETWORK, - href: APP_NETWORK_PATH, - disabled: false, - urlKey: 'network', - }, - [SecurityPageName.kubernetes]: { - id: SecurityPageName.kubernetes, - name: i18n.KUBERNETES, - href: APP_KUBERNETES_PATH, - disabled: false, - urlKey: 'kubernetes', - }, - [SecurityPageName.timelines]: { - id: SecurityPageName.timelines, - name: i18n.TIMELINES, - href: APP_TIMELINES_PATH, - disabled: false, - urlKey: 'timeline', - }, - [SecurityPageName.case]: { - id: SecurityPageName.case, - name: i18n.CASE, - href: APP_CASES_PATH, - disabled: false, - urlKey: 'cases', - }, - [SecurityPageName.endpoints]: { - id: SecurityPageName.endpoints, - name: i18n.ENDPOINTS, - href: APP_ENDPOINTS_PATH, - disabled: false, - urlKey: 'administration', - }, - [SecurityPageName.policies]: { - id: SecurityPageName.policies, - name: i18n.POLICIES, - href: APP_POLICIES_PATH, - disabled: false, - urlKey: 'administration', - }, - [SecurityPageName.trustedApps]: { - id: SecurityPageName.trustedApps, - name: i18n.TRUSTED_APPLICATIONS, - href: APP_TRUSTED_APPS_PATH, - disabled: false, - urlKey: 'administration', - }, - [SecurityPageName.eventFilters]: { - id: SecurityPageName.eventFilters, - name: i18n.EVENT_FILTERS, - href: APP_EVENT_FILTERS_PATH, - disabled: false, - urlKey: 'administration', - }, - [SecurityPageName.hostIsolationExceptions]: { - id: SecurityPageName.hostIsolationExceptions, - name: i18n.HOST_ISOLATION_EXCEPTIONS, - href: APP_HOST_ISOLATION_EXCEPTIONS_PATH, - disabled: false, - urlKey: 'administration', - }, - [SecurityPageName.blocklist]: { - id: SecurityPageName.blocklist, - name: i18n.BLOCKLIST, - href: APP_BLOCKLIST_PATH, - disabled: false, - urlKey: 'administration', - }, - [SecurityPageName.responseActionsHistory]: { - id: SecurityPageName.responseActionsHistory, - name: i18n.RESPONSE_ACTIONS_HISTORY, - href: APP_RESPONSE_ACTIONS_HISTORY_PATH, - disabled: false, - urlKey: 'administration', - }, - [SecurityPageName.threatIntelligenceIndicators]: { - ...getSecuritySolutionTINavTab('indicators', APP_PATH), - urlKey: 'indicators', - }, - [SecurityPageName.cloudSecurityPostureFindings]: { - ...getSecuritySolutionCSPNavTab('findings', APP_PATH), - urlKey: 'findings', - }, - [SecurityPageName.cloudSecurityPostureDashboard]: { - ...getSecuritySolutionCSPNavTab('dashboard', APP_PATH), - urlKey: 'cloud_posture', - }, - [SecurityPageName.cloudSecurityPostureBenchmarks]: { - ...getSecuritySolutionCSPNavTab('benchmarks', APP_PATH), - urlKey: 'administration', - }, - [SecurityPageName.cloudDefendPolicies]: { - ...getSecuritySolutionCloudDefendNavTab('policies', APP_PATH), - urlKey: 'administration', - }, - [SecurityPageName.entityAnalytics]: { - id: SecurityPageName.entityAnalytics, - name: i18n.ENTITY_ANALYTICS, - href: APP_ENTITY_ANALYTICS_PATH, - disabled: false, - urlKey: 'entity_analytics', - }, - [SecurityPageName.dataQuality]: { - id: SecurityPageName.dataQuality, - name: i18n.DATA_QUALITY, - href: APP_DATA_QUALITY_PATH, - disabled: false, - urlKey: 'data_quality', - }, -}; - -export const securityNavGroup: SecurityNavGroup = { - [SecurityNavGroupKey.dashboards]: { - id: SecurityNavGroupKey.dashboards, - name: i18n.DASHBOARDS, - }, - [SecurityNavGroupKey.detect]: { - id: SecurityNavGroupKey.detect, - name: i18n.DETECT, - }, - [SecurityNavGroupKey.findings]: { - id: SecurityNavGroupKey.findings, - name: i18n.FINDINGS, - }, - [SecurityNavGroupKey.explore]: { - id: SecurityNavGroupKey.explore, - name: i18n.EXPLORE, - }, - [SecurityNavGroupKey.intelligence]: { - id: SecurityNavGroupKey.intelligence, - name: i18n.THREAT_INTELLIGENCE, - }, - [SecurityNavGroupKey.investigate]: { - id: SecurityNavGroupKey.investigate, - name: i18n.INVESTIGATE, - }, - [SecurityNavGroupKey.manage]: { - id: SecurityNavGroupKey.manage, - name: i18n.MANAGE, - }, -}; diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx index a70a915e6aed4..c542ba649401e 100644 --- a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx @@ -25,8 +25,6 @@ import { } from './bottom_bar'; import { useShowTimeline } from '../../../common/utils/timeline/use_show_timeline'; import { useShowPagesWithEmptyView } from '../../../common/utils/empty_view/use_show_pages_with_empty_view'; -import { useIsPolicySettingsBarVisible } from '../../../management/pages/policy/view/policy_hooks'; -import { useIsGroupedNavigationEnabled } from '../../../common/components/navigation/helpers'; import { useSyncFlyoutStateWithUrl } from '../../../flyout/url/use_sync_flyout_state_with_url'; const NO_DATA_PAGE_MAX_WIDTH = 950; @@ -59,16 +57,12 @@ const StyledKibanaPageTemplate = styled(KibanaPageTemplate)< export const SecuritySolutionTemplateWrapper: React.FC> = React.memo(({ children, ...rest }) => { - const solutionNav = useSecuritySolutionNavigation(); - const isPolicySettingsVisible = useIsPolicySettingsBarVisible(); + const solutionNavProps = useSecuritySolutionNavigation(); const [isTimelineBottomBarVisible] = useShowTimeline(); const getTimelineShowStatus = useMemo(() => getTimelineShowStatusByIdSelector(), []); const { show: isShowingTimelineOverlay } = useDeepEqualSelector((state) => getTimelineShowStatus(state, TimelineId.active) ); - const isGroupedNavEnabled = useIsGroupedNavigationEnabled(); - const addBottomPadding = - isTimelineBottomBarVisible || isPolicySettingsVisible || isGroupedNavEnabled; // The bottomBar by default has a set 'dark' colorMode that doesn't match the global colorMode from the Advanced Settings // To keep the mode in sync, we pass in the globalColorMode to the bottom bar here @@ -91,10 +85,9 @@ export const SecuritySolutionTemplateWrapper: React.FC diff --git a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.test.tsx b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.test.tsx index c90327bc10929..4892940f09064 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.test.tsx @@ -8,12 +8,12 @@ import { render } from '@testing-library/react'; import React from 'react'; import { SecurityPageName } from '../../../app/types'; -import type { NavLinkItem } from '../navigation/types'; +import type { NavigationLink } from '../../links/types'; import { TestProviders } from '../../mock'; import { LandingLinksIcons } from './landing_links_icons'; import * as telemetry from '../../lib/telemetry'; -const DEFAULT_NAV_ITEM: NavLinkItem = { +const DEFAULT_NAV_ITEM: NavigationLink = { id: SecurityPageName.overview, title: 'TEST LABEL', description: 'TEST DESCRIPTION', diff --git a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.tsx b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.tsx index eddaa063aa783..7fc6fb453fd91 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_icons.tsx @@ -10,11 +10,11 @@ import styled from 'styled-components'; import { NavItemBetaBadge } from '../navigation/nav_item_beta_badge'; import { SecuritySolutionLinkAnchor, withSecuritySolutionLink } from '../links'; -import type { NavLinkItem } from '../navigation/types'; +import type { NavigationLink } from '../../links/types'; import { METRIC_TYPE, TELEMETRY_EVENT, track } from '../../lib/telemetry'; interface LandingLinksImagesProps { - items: NavLinkItem[]; + items: NavigationLink[]; } const Link = styled.a` diff --git a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.test.tsx b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.test.tsx index 69dbf83877edd..39b5ed53cf9e4 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.test.tsx @@ -9,19 +9,19 @@ import { render } from '@testing-library/react'; import React from 'react'; import { BETA } from '@kbn/kubernetes-security-plugin/common/translations'; import { SecurityPageName } from '../../../app/types'; -import type { NavLinkItem } from '../navigation/types'; +import type { NavigationLink } from '../../links/types'; import { TestProviders } from '../../mock'; import { LandingLinksImages, LandingImageCards } from './landing_links_images'; import * as telemetry from '../../lib/telemetry'; -const DEFAULT_NAV_ITEM: NavLinkItem = { +const DEFAULT_NAV_ITEM: NavigationLink = { id: SecurityPageName.overview, title: 'TEST LABEL', description: 'TEST DESCRIPTION', image: 'TEST_IMAGE.png', }; -const BETA_NAV_ITEM: NavLinkItem = { +const BETA_NAV_ITEM: NavigationLink = { id: SecurityPageName.kubernetes, title: 'TEST LABEL', description: 'TEST DESCRIPTION', diff --git a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.tsx b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.tsx index 6bd4d51bd8618..b1510c65d5bf4 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_links/landing_links_images.tsx @@ -18,11 +18,11 @@ import React from 'react'; import styled from 'styled-components'; import { withSecuritySolutionLink } from '../links'; import { NavItemBetaBadge } from '../navigation/nav_item_beta_badge'; -import type { NavLinkItem } from '../navigation/types'; +import type { NavigationLink } from '../../links/types'; import { TELEMETRY_EVENT, track } from '../../lib/telemetry'; interface LandingImagesProps { - items: NavLinkItem[]; + items: NavigationLink[]; } const PrimaryEuiTitle = styled(EuiTitle)` 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 index f6873cfec71ad..325f490a351b1 100644 --- 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 @@ -12,13 +12,10 @@ import { getAppLandingUrl } from '../../link_to/redirect_to_landing'; import type { GetSecuritySolutionUrl } from '../../link_to'; import { getAncestorLinksInfo } from '../../../links'; -import type { GenericNavRecord } from '../types'; export const getLeadingBreadcrumbsForSecurityPage = ( pageName: SecurityPageName, - getSecuritySolutionUrl: GetSecuritySolutionUrl, - navTabs: GenericNavRecord, - isGroupedNavigationEnabled: boolean + getSecuritySolutionUrl: GetSecuritySolutionUrl ): [ChromeBreadcrumb, ...ChromeBreadcrumb[]] => { const landingPath = getSecuritySolutionUrl({ deepLinkId: SecurityPageName.landing }); @@ -27,16 +24,10 @@ export const getLeadingBreadcrumbsForSecurityPage = ( href: getAppLandingUrl(landingPath), }; - const breadcrumbs: ChromeBreadcrumb[] = getAncestorLinksInfo(pageName).map(({ title, id }) => { - const newTitle = title; - // Get title from navTabs because pages title on the new structure might be different. - const oldTitle = navTabs[id] ? navTabs[id].name : title; - - return { - text: isGroupedNavigationEnabled ? newTitle : oldTitle, - href: getSecuritySolutionUrl({ deepLinkId: id }), - }; - }); + 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 index c5b0f8c2bfb06..d0bd1d56f9e01 100644 --- 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 @@ -7,53 +7,35 @@ import '../../../mock/match_media'; import { encodeIpv6 } from '../../../lib/helpers'; -import type { ObjectWithNavTabs } from '.'; -import { getBreadcrumbsForRoute, useSetBreadcrumbs } from '.'; +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 { TimelineTabs } from '../../../../../common/types/timeline'; 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 { useDeepEqualSelector } from '../../../hooks/use_selector'; -import { useIsGroupedNavigationEnabled } from '../helpers'; -import { navTabs } from '../../../../app/home/home_navigations'; 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'; -jest.mock('../../../hooks/use_selector'); - -const mockUseIsGroupedNavigationEnabled = useIsGroupedNavigationEnabled as jest.Mock; -jest.mock('../helpers', () => { - const original = jest.requireActual('../helpers'); - return { - ...original, - useIsGroupedNavigationEnabled: jest.fn(), - }; -}); - -const setBreadcrumbsMock = jest.fn(); -const chromeMock = { - setBreadcrumbs: setBreadcrumbsMock, - // eslint-disable-next-line @typescript-eslint/no-explicit-any -} as any; +const mockUseRouteSpy = jest.fn(); +jest.mock('../../../utils/route/use_route_spy', () => ({ + useRouteSpy: () => mockUseRouteSpy(), +})); const getMockObject = ( pageName: SecurityPageName, pathName: string, detailName: string | undefined -): RouteSpyState & ObjectWithNavTabs => { +): RouteSpyState => { switch (pageName) { case SecurityPageName.hosts: return { detailName, - navTabs, pageName, pathName, search: '', @@ -63,7 +45,6 @@ const getMockObject = ( case SecurityPageName.users: return { detailName, - navTabs, pageName, pathName, search: '', @@ -73,7 +54,6 @@ const getMockObject = ( case SecurityPageName.network: return { detailName, - navTabs, pageName, pathName, search: '', @@ -83,7 +63,6 @@ const getMockObject = ( case SecurityPageName.administration: return { detailName, - navTabs, pageName, pathName, search: '', @@ -93,7 +72,6 @@ const getMockObject = ( case SecurityPageName.alerts: return { detailName, - navTabs, pageName, pathName, search: '', @@ -103,29 +81,13 @@ const getMockObject = ( default: return { detailName, - navTabs, pageName, pathName, search: '', - } as RouteSpyState & ObjectWithNavTabs; + } as RouteSpyState; } }; -(useDeepEqualSelector as jest.Mock).mockImplementation(() => { - return { - urlState: { - query: { query: '', language: 'kuery' }, - filters: [], - timeline: { - activeTab: TimelineTabs.query, - id: '', - isOpen: false, - graphEventId: '', - }, - }, - }; -}); - // The string returned is different from what getSecuritySolutionUrl returns, but does not matter for the purposes of this test. const getSecuritySolutionUrl: GetSecuritySolutionUrl = ({ deepLinkId, @@ -136,11 +98,14 @@ const getSecuritySolutionUrl: GetSecuritySolutionUrl = ({ absolute?: boolean; }) => `${APP_UI_ID}${deepLinkId ? `/${deepLinkId}` : ''}${path ?? ''}`; +const mockSetBreadcrumbs = jest.fn(); jest.mock('../../../lib/kibana/kibana_react', () => { return { useKibana: () => ({ services: { - chrome: undefined, + chrome: { + setBreadcrumbs: mockSetBreadcrumbs, + }, application: { navigateToApp: jest.fn(), getUrlForApp: (appId: string, options?: { path?: string; deepLinkId?: boolean }) => @@ -151,6 +116,12 @@ jest.mock('../../../lib/kibana/kibana_react', () => { }; }); +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', @@ -203,730 +174,369 @@ describe('Navigation Breadcrumbs', () => { }); }); - const hostName = 'siem-kibana'; - - const ipv4 = '192.0.2.255'; - const ipv6 = '2001:db8:ffff:ffff:ffff:ffff:ffff:ffff'; - const ipv6Encoded = encodeIpv6(ipv6); + beforeEach(() => { + jest.clearAllMocks(); + }); - describe('Old Architecture', () => { - beforeAll(() => { - mockUseIsGroupedNavigationEnabled.mockReturnValue(false); + 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', + }, + ]); }); - describe('getBreadcrumbsForRoute', () => { - test('should return Overview breadcrumbs when supplied overview pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.overview, '/', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - href: '', - text: 'Overview', - }, - ]); - }); - - test('should return Host breadcrumbs when supplied hosts pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.hosts, '/', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - hostsBreadcrumbs, - { - href: '', - text: 'Authentications', - }, - ]); - }); - - test('should return Network breadcrumbs when supplied network pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - networkBreadcrumb, - { - text: 'Flows', - href: '', - }, - ]); - }); - - test('should return Timelines breadcrumbs when supplied timelines pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.timelines, '/', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - text: 'Timelines', - href: '', - }, - ]); - }); - - test('should return Host Details breadcrumbs when supplied a pathname with hostName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.hosts, '/', hostName), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - hostsBreadcrumbs, - { - text: 'siem-kibana', - href: 'securitySolutionUI/hosts/name/siem-kibana', - }, - { text: 'Authentications', href: '' }, - ]); - }); - - test('should return IP Details breadcrumbs when supplied pathname with ipv4', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', ipv4), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - networkBreadcrumb, - { - text: ipv4, - href: `securitySolutionUI/network/ip/${ipv4}/source/flows`, - }, - { text: 'Flows', href: '' }, - ]); - }); - - test('should return IP Details breadcrumbs when supplied pathname with ipv6', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', ipv6Encoded), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - networkBreadcrumb, - { - text: ipv6, - href: `securitySolutionUI/network/ip/${ipv6Encoded}/source/flows`, - }, - { text: 'Flows', href: '' }, - ]); - }); - - test('should return Alerts breadcrumbs when supplied alerts pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.alerts, '/alerts', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - text: 'Alerts', - href: 'securitySolutionUI/alerts', - }, - { - text: 'Summary', - href: '', - }, - ]); - }); - - test('should return Exceptions breadcrumbs when supplied exceptions pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.exceptions, '/exceptions', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - text: 'Shared Exception Lists', - href: '', - }, - ]); - }); - - test('should return Rules breadcrumbs when supplied rules pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.rules, '/rules', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - text: 'Rules', - href: '', - }, - ]); - }); - - test('should return Rules breadcrumbs when supplied rules Creation pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.rules, '/rules/create', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - rulesBReadcrumb, - { - text: 'Create', - href: '', - }, - ]); - }); - - test('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, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - rulesBReadcrumb, - { - text: 'ALERT_RULE_NAME', - href: `securitySolutionUI/rules/id/${mockDetailName}`, - }, - { - text: 'Deleted rule', - href: '', - }, - ]); - }); - - test('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, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - rulesBReadcrumb, - { - text: 'ALERT_RULE_NAME', - href: `securitySolutionUI/rules/id/${mockDetailName}`, - }, - { - text: 'Edit', - href: '', - }, - ]); - }); - - test('should return null breadcrumbs when supplied Cases pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.case, '/', undefined), - getSecuritySolutionUrl, - false - ); - expect(breadcrumbs).toEqual(null); - }); - - test('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, - false - ); - expect(breadcrumbs).toEqual(null); - }); - - test('should return Endpoints breadcrumbs when supplied endpoints pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.endpoints, '/endpoints', undefined), - getSecuritySolutionUrl, - false - ); - - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - text: 'Endpoints', - href: '', - }, - ]); - }); - - test('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, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - exceptionsBReadcrumb, - { - text: mockListName, - href: ``, - }, - ]); - }); + it('should return Host breadcrumbs when supplied hosts pageName', () => { + const breadcrumbs = getBreadcrumbsForRoute( + getMockObject(SecurityPageName.hosts, '/', undefined), + getSecuritySolutionUrl + ); + expect(breadcrumbs).toEqual([ + securityBreadCrumb, + exploreBreadcrumbs, + hostsBreadcrumbs, + { + href: '', + text: 'Authentications', + }, + ]); }); - describe('setBreadcrumbs()', () => { - test('should call chrome breadcrumb service with correct breadcrumbs', () => { - const navigateToUrlMock = jest.fn(); - const { result } = renderHook(() => useSetBreadcrumbs(), { wrapper: TestProviders }); - result.current( - getMockObject(SecurityPageName.hosts, '/', hostName), - chromeMock, - navigateToUrlMock - ); - - expect(setBreadcrumbsMock).toBeCalledWith([ - expect.objectContaining({ - text: 'Security', - href: 'securitySolutionUI/get_started', - 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 return Network breadcrumbs when supplied network pageName', () => { + const breadcrumbs = getBreadcrumbsForRoute( + getMockObject(SecurityPageName.network, '/', undefined), + getSecuritySolutionUrl + ); + expect(breadcrumbs).toEqual([ + securityBreadCrumb, + exploreBreadcrumbs, + networkBreadcrumb, + { + text: 'Flows', + href: '', + }, + ]); }); - }); - describe('New Architecture', () => { - beforeAll(() => { - mockUseIsGroupedNavigationEnabled.mockReturnValue(true); + it('should return Timelines breadcrumbs when supplied timelines pageName', () => { + const breadcrumbs = getBreadcrumbsForRoute( + getMockObject(SecurityPageName.timelines, '/', undefined), + getSecuritySolutionUrl + ); + expect(breadcrumbs).toEqual([ + securityBreadCrumb, + { + text: 'Timelines', + href: '', + }, + ]); }); - describe('getBreadcrumbsForRoute', () => { - test('should return Overview breadcrumbs when supplied overview pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.overview, '/', undefined), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - href: 'securitySolutionUI/dashboards', - text: 'Dashboards', - }, - { - href: '', - text: 'Overview', - }, - ]); - }); - - test('should return Host breadcrumbs when supplied hosts pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.hosts, '/', undefined), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - exploreBreadcrumbs, - hostsBreadcrumbs, - { - href: '', - text: 'Authentications', - }, - ]); - }); - - test('should return Network breadcrumbs when supplied network pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', undefined), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - exploreBreadcrumbs, - networkBreadcrumb, - { - text: 'Flows', - href: '', - }, - ]); - }); - - test('should return Timelines breadcrumbs when supplied timelines pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.timelines, '/', undefined), - getSecuritySolutionUrl, - true - ); - 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, + exploreBreadcrumbs, + hostsBreadcrumbs, + { + text: 'siem-kibana', + href: 'securitySolutionUI/hosts/name/siem-kibana', + }, + { text: 'Authentications', href: '' }, + ]); + }); - test('should return Host Details breadcrumbs when supplied a pathname with hostName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.hosts, '/', hostName), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - exploreBreadcrumbs, - hostsBreadcrumbs, - { - 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, + exploreBreadcrumbs, + networkBreadcrumb, + { + text: ipv4, + href: `securitySolutionUI/network/ip/${ipv4}/source/flows`, + }, + { text: 'Flows', href: '' }, + ]); + }); - test('should return IP Details breadcrumbs when supplied pathname with ipv4', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', ipv4), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - exploreBreadcrumbs, - 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, + exploreBreadcrumbs, + networkBreadcrumb, + { + text: ipv6, + href: `securitySolutionUI/network/ip/${ipv6Encoded}/source/flows`, + }, + { text: 'Flows', href: '' }, + ]); + }); - test('should return IP Details breadcrumbs when supplied pathname with ipv6', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.network, '/', ipv6Encoded), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - exploreBreadcrumbs, - 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: '', + }, + ]); + }); - test('should return Alerts breadcrumbs when supplied alerts pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.alerts, '/alerts', undefined), - getSecuritySolutionUrl, - true - ); - 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, + manageBreadcrumbs, + { + text: 'Shared Exception Lists', + href: '', + }, + ]); + }); - test('should return Exceptions breadcrumbs when supplied exceptions pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.exceptions, '/exceptions', undefined), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - manageBreadcrumbs, - { - 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, + manageBreadcrumbs, + { + text: 'Rules', + href: '', + }, + ]); + }); - test('should return Rules breadcrumbs when supplied rules pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.rules, '/rules', undefined), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - manageBreadcrumbs, - { - text: 'Rules', - 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, + manageBreadcrumbs, + rulesBReadcrumb, + { + text: 'Create', + href: '', + }, + ]); + }); - test('should return Rules breadcrumbs when supplied rules Creation pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.rules, '/rules/create', undefined), - getSecuritySolutionUrl, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - manageBreadcrumbs, - 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, + manageBreadcrumbs, + rulesBReadcrumb, + { + text: mockRuleName, + href: `securitySolutionUI/rules/id/${mockDetailName}`, + }, + { + text: 'Deleted rule', + href: '', + }, + ]); + }); - test('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, - }, + 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, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - manageBreadcrumbs, - rulesBReadcrumb, - { - text: mockRuleName, - href: `securitySolutionUI/rules/id/${mockDetailName}`, - }, - { - text: 'Deleted rule', - href: '', - }, - ]); - }); + }, + getSecuritySolutionUrl + ); + expect(breadcrumbs).toEqual([ + securityBreadCrumb, + manageBreadcrumbs, + rulesBReadcrumb, + { + text: 'ALERT_RULE_NAME', + href: `securitySolutionUI/rules/id/${mockDetailName}`, + }, + { + text: 'Edit', + href: '', + }, + ]); + }); - test('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, - true - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - manageBreadcrumbs, - 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); + }); - test('should return null breadcrumbs when supplied Cases pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.case, '/', undefined), - getSecuritySolutionUrl, - true - ); - 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); + }); - test('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, - true - ); - 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, + manageBreadcrumbs, + { + text: 'Endpoints', + href: '', + }, + ]); + }); - test('should return Endpoints breadcrumbs when supplied endpoints pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.endpoints, '/', undefined), - getSecuritySolutionUrl, - true - ); - - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - manageBreadcrumbs, - { - text: 'Endpoints', - href: '', + it('should return Admin breadcrumbs when supplied admin pageName', () => { + const breadcrumbs = getBreadcrumbsForRoute( + getMockObject(SecurityPageName.administration, '/', undefined), + getSecuritySolutionUrl + ); + + expect(breadcrumbs).toEqual([ + securityBreadCrumb, + { + text: 'Manage', + 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, + manageBreadcrumbs, + exceptionsBReadcrumb, + { + text: mockListName, + href: ``, + }, + ]); + }); + }); - test('should return Admin breadcrumbs when supplied admin pageName', () => { - const breadcrumbs = getBreadcrumbsForRoute( - getMockObject(SecurityPageName.administration, '/', undefined), - getSecuritySolutionUrl, - true - ); - - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - { - text: 'Manage', - href: '', - }, - ]); - }); - test('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, - false - ); - expect(breadcrumbs).toEqual([ - securityBreadCrumb, - 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: '', + }, + ]); }); - describe('setBreadcrumbs()', () => { - test('should call chrome breadcrumb service with correct breadcrumbs', () => { - const navigateToUrlMock = jest.fn(); - const { result } = renderHook(() => useSetBreadcrumbs(), { wrapper: TestProviders }); - result.current( - getMockObject(SecurityPageName.hosts, '/', hostName), - chromeMock, - navigateToUrlMock - ); - - expect(setBreadcrumbsMock).toBeCalledWith([ - 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 2b0258d74a45f..fdaa1e04a00e1 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 @@ -5,14 +5,13 @@ * 2.0. */ -import { last, omit } from 'lodash/fp'; - +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 type { StartServices } from '../../../../types'; import { getTrailingBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../../explore/hosts/pages/details/utils'; -import { getTrailingBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../explore/network/pages/details'; +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'; @@ -24,46 +23,39 @@ 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 { GenericNavRecord, NavigateToUrl } from '../types'; import { getLeadingBreadcrumbsForSecurityPage } from './get_breadcrumbs_for_page'; import type { GetSecuritySolutionUrl } from '../../link_to'; import { useGetSecuritySolutionUrl } from '../../link_to'; -import { useIsGroupedNavigationEnabled } from '../helpers'; import { TELEMETRY_EVENT, track } from '../../../lib/telemetry'; +import { useKibana } from '../../../lib/kibana'; +import { useRouteSpy } from '../../../utils/route/use_route_spy'; -export interface ObjectWithNavTabs { - navTabs: GenericNavRecord; -} - -export const useSetBreadcrumbs = () => { +export const useBreadcrumbs = ({ isEnabled }: { isEnabled: boolean }) => { const dispatch = useDispatch(); + const [routeProps] = useRouteSpy(); const getSecuritySolutionUrl = useGetSecuritySolutionUrl(); - const isGroupedNavigationEnabled = useIsGroupedNavigationEnabled(); - - return ( - spyState: RouteSpyState & ObjectWithNavTabs, - chrome: StartServices['chrome'], - navigateToUrl: NavigateToUrl - ) => { - const breadcrumbs = getBreadcrumbsForRoute( - spyState, - getSecuritySolutionUrl, - isGroupedNavigationEnabled - ); + const { + chrome: { setBreadcrumbs }, + application: { navigateToUrl }, + } = useKibana().services; + useEffect(() => { + if (!isEnabled) { + return; + } + const breadcrumbs = getBreadcrumbsForRoute(routeProps, getSecuritySolutionUrl); if (!breadcrumbs) { return; } - - chrome.setBreadcrumbs( + setBreadcrumbs( breadcrumbs.map((breadcrumb) => ({ ...breadcrumb, ...(breadcrumb.href && !breadcrumb.onClick ? { onClick: (ev) => { ev.preventDefault(); - const trakedPath = breadcrumb.href?.split('?')[0] ?? 'unknown'; - track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.BREADCRUMB}${trakedPath}`); + 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 @@ -73,40 +65,26 @@ export const useSetBreadcrumbs = () => { : {}), })) ); - }; + }, [routeProps, isEnabled, dispatch, getSecuritySolutionUrl, setBreadcrumbs, navigateToUrl]); }; export const getBreadcrumbsForRoute = ( - object: RouteSpyState & ObjectWithNavTabs, - getSecuritySolutionUrl: GetSecuritySolutionUrl, - isGroupedNavigationEnabled: boolean + spyState: RouteSpyState, + getSecuritySolutionUrl: GetSecuritySolutionUrl ): ChromeBreadcrumb[] | null => { - const spyState = omit('navTabs', object) as RouteSpyState; - if ( - !spyState || - !object.navTabs || - !spyState.pageName || + !spyState?.pageName || + // cases manages its own breadcrumbs, return null spyState.pageName === SecurityPageName.case ) { return null; } - const newMenuLeadingBreadcrumbs = getLeadingBreadcrumbsForSecurityPage( + const leadingBreadcrumbs = getLeadingBreadcrumbsForSecurityPage( spyState.pageName, - getSecuritySolutionUrl, - object.navTabs, - isGroupedNavigationEnabled + getSecuritySolutionUrl ); - // last newMenuLeadingBreadcrumbs is the current page - const pageBreadcrumb = newMenuLeadingBreadcrumbs[newMenuLeadingBreadcrumbs.length - 1]; - const siemRootBreadcrumb = newMenuLeadingBreadcrumbs[0]; - - const leadingBreadcrumbs = isGroupedNavigationEnabled - ? newMenuLeadingBreadcrumbs - : [siemRootBreadcrumb, pageBreadcrumb]; - return emptyLastBreadcrumbUrl([ ...leadingBreadcrumbs, ...getTrailingBreadcrumbsForRoutes(spyState, getSecuritySolutionUrl), diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts b/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts index 28f402769f337..dbf05e1220ac6 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts @@ -5,19 +5,8 @@ * 2.0. */ -import { useUiSetting$ } from '../../lib/kibana'; import type { SecurityPageName } from '../../../../common/constants'; -import { ENABLE_GROUPED_NAVIGATION } from '../../../../common/constants'; import { needsUrlState } from '../../links'; export const getSearch = (pageName: SecurityPageName, globalQueryString: string): string => needsUrlState(pageName) && globalQueryString.length > 0 ? `?${globalQueryString}` : ''; - -/** - * Hook to check if the new grouped navigation is enabled on both experimental flag and advanced settings - * TODO: remove this function when flag and setting not needed - */ -export const useIsGroupedNavigationEnabled = () => { - const [groupedNavSettingEnabled] = useUiSetting$(ENABLE_GROUPED_NAVIGATION); - return groupedNavSettingEnabled; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.test.tsx index a0612e9b63897..ea250ee1ff484 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.test.tsx @@ -12,11 +12,11 @@ import { SecurityPageName } from '../../../../app/types'; import { TestProviders } from '../../../mock'; import { BOTTOM_BAR_HEIGHT, EUI_HEADER_HEIGHT, SecuritySideNav } from './security_side_nav'; import type { SolutionSideNavProps } from '@kbn/security-solution-side-nav'; -import type { NavLinkItem } from '../types'; +import type { NavigationLink } from '../../../links/types'; import { track } from '../../../lib/telemetry'; import { useKibana } from '../../../lib/kibana'; -const manageNavLink: NavLinkItem = { +const manageNavLink: NavigationLink = { id: SecurityPageName.administration, title: 'manage', description: 'manage description', @@ -30,7 +30,7 @@ const manageNavLink: NavLinkItem = { }, ], }; -const alertsNavLink: NavLinkItem = { +const alertsNavLink: NavigationLink = { id: SecurityPageName.alerts, title: 'alerts', description: 'alerts description', diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.tsx index abc4350eb83fa..d73c3725f80f9 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.tsx @@ -5,112 +5,4 @@ * 2.0. */ -import { EuiTab, EuiTabs, EuiBetaBadge } from '@elastic/eui'; -import { getOr } from 'lodash/fp'; -import React, { useEffect, useState, useCallback, useMemo } from 'react'; -import { useLocation } from 'react-router-dom'; -import deepEqual from 'fast-deep-equal'; - -import { useNavigation } from '../../../lib/kibana'; -import { track, METRIC_TYPE, TELEMETRY_EVENT } from '../../../lib/telemetry'; -import type { TabNavigationProps, TabNavigationItemProps } from './types'; -import { BETA } from '../../../translations'; - -const TabNavigationItemComponent = ({ - disabled, - hrefWithSearch, - id, - name, - isSelected, - isBeta, - betaOptions, -}: TabNavigationItemProps) => { - const { getAppUrl, navigateTo } = useNavigation(); - - const handleClick = useCallback( - (ev) => { - ev.preventDefault(); - navigateTo({ path: hrefWithSearch }); - track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${id}`); - }, - [navigateTo, hrefWithSearch, id] - ); - - const appHref = getAppUrl({ - path: hrefWithSearch, - }); - - return ( - } - > - {name} - - ); -}; - -const TabNavigationItem = React.memo(TabNavigationItemComponent); - -export const TabNavigationComponent: React.FC = ({ navTabs, tabName }) => { - const mapLocationToTab = useCallback( - (): string => - getOr( - '', - 'id', - Object.values(navTabs).find((item) => tabName === item.id) - ), - [tabName, navTabs] - ); - const [selectedTabId, setSelectedTabId] = useState(mapLocationToTab()); - useEffect(() => { - const currentTabSelected = mapLocationToTab(); - - if (currentTabSelected !== selectedTabId) { - setSelectedTabId(currentTabSelected); - } - - // we do need navTabs in case the selectedTabId appears after initial load (ex. checking permissions for anomalies) - }, [tabName, navTabs, mapLocationToTab, selectedTabId]); - - const { search } = useLocation(); - - const renderTabs = useMemo( - () => - Object.values(navTabs).map((tab) => { - const isSelected = selectedTabId === tab.id; - return ( - - ); - }), - [navTabs, selectedTabId, search] - ); - - return {renderTabs}; -}; - -TabNavigationComponent.displayName = 'TabNavigationComponent'; - -export const TabNavigation = React.memo( - TabNavigationComponent, - (prevProps, nextProps) => - prevProps.display === nextProps.display && - prevProps.tabName === nextProps.tabName && - deepEqual(prevProps.navTabs, nextProps.navTabs) -); - -TabNavigation.displayName = 'TabNavigation'; +export { TabNavigation } from './tab_navigation'; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.test.tsx similarity index 76% rename from x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.test.tsx index ad51ea40cf466..752d02f1498ba 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.test.tsx @@ -9,11 +9,13 @@ import { mount } from 'enzyme'; import React from 'react'; import { navTabsHostDetails } from '../../../../explore/hosts/pages/details/nav_tabs'; import { HostsTableType } from '../../../../explore/hosts/store/model'; -import type { RouteSpyState } from '../../../utils/route/types'; -import { TabNavigationComponent } from '.'; +import { TabNavigationComponent } from './tab_navigation'; import type { TabNavigationProps } from './types'; -import { SecurityPageName } from '../../../../app/types'; +const mockUseRouteSpy = jest.fn(); +jest.mock('../../../utils/route/use_route_spy', () => ({ + useRouteSpy: () => mockUseRouteSpy(), +})); jest.mock('../../link_to'); jest.mock('../../../lib/kibana/kibana_react', () => { const originalModule = jest.requireActual('../../../lib/kibana/kibana_react'); @@ -50,38 +52,31 @@ const hostName = 'siem-window'; describe('Table Navigation', () => { const mockHasMlUserPermissions = true; const mockRiskyHostEnabled = true; + mockUseRouteSpy.mockReturnValue([{ tabName: HostsTableType.authentications }]); - const mockProps: TabNavigationProps & RouteSpyState = { - pageName: SecurityPageName.hosts, - pathName: '/hosts', - detailName: hostName, - search: '', - tabName: HostsTableType.authentications, + const mockProps: TabNavigationProps = { navTabs: navTabsHostDetails({ hostName, hasMlUserPermissions: mockHasMlUserPermissions, isRiskyHostsEnabled: mockRiskyHostEnabled, }), }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + test('it mounts with correct tab highlighted', () => { const wrapper = mount(); - const tableNavigationTab = wrapper.find( + const authNavigationTab = wrapper.find( `EuiTab[data-test-subj="navigation-${HostsTableType.authentications}"]` ); - - expect(tableNavigationTab.prop('isSelected')).toBeTruthy(); - }); - test('it changes active tab when nav changes by props', () => { - const wrapper = mount(); - const tableNavigationTab = () => + expect(authNavigationTab.prop('isSelected')).toBeTruthy(); + const eventsNavigationTab = () => wrapper.find(`[data-test-subj="navigation-${HostsTableType.events}"]`).first(); - expect(tableNavigationTab().prop('isSelected')).toBeFalsy(); - wrapper.setProps({ - tabName: HostsTableType.events, - }); - wrapper.update(); - expect(tableNavigationTab().prop('isSelected')).toBeTruthy(); + expect(eventsNavigationTab().prop('isSelected')).toBeFalsy(); }); + test('it carries the url state in the link', () => { const wrapper = mount(); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx new file mode 100644 index 0000000000000..f903611a3bf96 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/tab_navigation.tsx @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiTab, EuiTabs, EuiBetaBadge } from '@elastic/eui'; +import { getOr } from 'lodash/fp'; +import React, { useEffect, useState, useCallback, useMemo } from 'react'; +import { useLocation } from 'react-router-dom'; +import deepEqual from 'fast-deep-equal'; + +import { useNavigation } from '../../../lib/kibana'; +import { track, METRIC_TYPE, TELEMETRY_EVENT } from '../../../lib/telemetry'; +import type { TabNavigationProps, TabNavigationItemProps } from './types'; +import { BETA } from '../../../translations'; +import { useRouteSpy } from '../../../utils/route/use_route_spy'; + +const TabNavigationItemComponent = ({ + disabled, + hrefWithSearch, + id, + name, + isSelected, + isBeta, + betaOptions, +}: TabNavigationItemProps) => { + const { getAppUrl, navigateTo } = useNavigation(); + + const handleClick = useCallback( + (ev) => { + ev.preventDefault(); + navigateTo({ path: hrefWithSearch }); + track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${id}`); + }, + [navigateTo, hrefWithSearch, id] + ); + + const appHref = getAppUrl({ + path: hrefWithSearch, + }); + + return ( + } + > + {name} + + ); +}; + +const TabNavigationItem = React.memo(TabNavigationItemComponent); + +export const TabNavigationComponent: React.FC = ({ navTabs }) => { + const [{ tabName }] = useRouteSpy(); + const mapLocationToTab = useCallback( + (): string => + getOr( + '', + 'id', + Object.values(navTabs).find((item) => tabName === item.id) + ), + [tabName, navTabs] + ); + const [selectedTabId, setSelectedTabId] = useState(mapLocationToTab()); + useEffect(() => { + const currentTabSelected = mapLocationToTab(); + + if (currentTabSelected !== selectedTabId) { + setSelectedTabId(currentTabSelected); + } + + // we do need navTabs in case the selectedTabId appears after initial load (ex. checking permissions for anomalies) + }, [tabName, navTabs, mapLocationToTab, selectedTabId]); + + const { search } = useLocation(); + + const renderTabs = useMemo( + () => + Object.values(navTabs).map((tab) => { + const isSelected = selectedTabId === tab.id; + return ( + + ); + }), + [navTabs, selectedTabId, search] + ); + + return {renderTabs}; +}; + +TabNavigationComponent.displayName = 'TabNavigationComponent'; + +export const TabNavigation = React.memo(TabNavigationComponent, (prevProps, nextProps) => + deepEqual(prevProps.navTabs, nextProps.navTabs) +); + +TabNavigation.displayName = 'TabNavigation'; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts index 2493023e08b8f..eda6b0c70caec 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts @@ -5,12 +5,10 @@ * 2.0. */ -import type { SecuritySolutionTabNavigationProps } from '../types'; +import type { NavTab } from '../types'; -export interface TabNavigationProps extends SecuritySolutionTabNavigationProps { - pathName: string; - pageName: string; - tabName?: string; +export interface TabNavigationProps { + navTabs: Record; } export interface TabNavigationItemProps { diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.test.tsx deleted file mode 100644 index ec6fd41a19609..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.test.tsx +++ /dev/null @@ -1,143 +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 { render } from '@testing-library/react'; -import React from 'react'; - -import { useRouteSpy } from '../../utils/route/use_route_spy'; -import { navTabs } from '../../../app/home/home_navigations'; - -import type { SecuritySolutionTabNavigationProps } from './types'; -import { TabNavigationWithBreadcrumbs } from './tab_navigation_with_breadcrumbs'; - -jest.mock('react-router-dom', () => { - const original = jest.requireActual('react-router-dom'); - - return { - ...original, - useHistory: () => ({ - useHistory: jest.fn(), - }), - }; -}); - -const mockSetBreadcrumbs = jest.fn(); - -jest.mock('./breadcrumbs', () => ({ - useSetBreadcrumbs: () => mockSetBreadcrumbs, -})); -const mockGetUrlForApp = jest.fn(); -const mockNavigateToUrl = jest.fn(); -jest.mock('../../lib/kibana/kibana_react', () => { - return { - useKibana: () => ({ - services: { - chrome: undefined, - application: { - navigateToApp: jest.fn(), - getUrlForApp: mockGetUrlForApp, - navigateToUrl: mockNavigateToUrl, - }, - }, - }), - }; -}); -jest.mock('../link_to'); -jest.mock('../../utils/route/use_route_spy'); - -jest.mock('react-router-dom', () => ({ - useLocation: jest.fn(() => ({ - search: '', - })), - useHistory: jest.fn(), -})); - -describe('SIEM Navigation', () => { - const mockProps: SecuritySolutionTabNavigationProps = { - navTabs, - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - test('it calls setBreadcrumbs with correct path on mount', () => { - (useRouteSpy as jest.Mock).mockReturnValueOnce([ - { - pageName: 'hosts', - pathName: '/', - savedQuery: undefined, - search: '', - state: undefined, - tabName: 'authentications', - }, - ]); - - render(); - - expect(mockSetBreadcrumbs).toHaveBeenNthCalledWith( - 1, - { - detailName: undefined, - navTabs, - pageName: 'hosts', - pathName: '/', - search: '', - state: undefined, - tabName: 'authentications', - flowTarget: undefined, - savedQuery: undefined, - }, - undefined, - mockNavigateToUrl - ); - }); - - test('it calls setBreadcrumbs with correct path on update', () => { - (useRouteSpy as jest.Mock) - .mockReturnValueOnce([ - { - pageName: 'hosts', - pathName: '/', - savedQuery: undefined, - search: '', - state: undefined, - tabName: 'authentications', - }, - ]) - .mockReturnValue([ - { - pageName: 'network', - pathName: '/', - savedQuery: undefined, - search: '', - state: undefined, - tabName: 'authentications', - }, - ]); - - const { rerender } = render(); - - rerender(); - - expect(mockSetBreadcrumbs).toHaveBeenNthCalledWith( - 2, - { - detailName: undefined, - flowTarget: undefined, - navTabs, - search: '', - pageName: 'network', - pathName: '/', - state: undefined, - tabName: 'authentications', - }, - undefined, - mockNavigateToUrl - ); - }); -}); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.tsx deleted file mode 100644 index 836a333539a37..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation_with_breadcrumbs.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect } from 'react'; - -import { useKibana } from '../../lib/kibana'; -import { useRouteSpy } from '../../utils/route/use_route_spy'; -import { useSetBreadcrumbs } from './breadcrumbs'; -import { TabNavigation } from './tab_navigation'; -import type { SecuritySolutionTabNavigationProps } from './types'; - -export function TabNavigationWithBreadcrumbs({ - navTabs, - display, -}: SecuritySolutionTabNavigationProps): JSX.Element { - const [routeState] = useRouteSpy(); - const { - chrome, - application: { getUrlForApp, navigateToUrl }, - } = useKibana().services; - const setBreadcrumbs = useSetBreadcrumbs(); - - useEffect(() => { - if (!routeState.pathName && !routeState.pageName) { - return; - } - - setBreadcrumbs({ ...routeState, navTabs }, chrome, navigateToUrl); - }, [chrome, routeState, navTabs, getUrlForApp, navigateToUrl, setBreadcrumbs]); - - return ( - - ); -} - -TabNavigationWithBreadcrumbs.displayName = 'TabNavigationWithBreadcrumbs'; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/types.ts b/x-pack/plugins/security_solution/public/common/components/navigation/types.ts index 29f69700afdb7..d185aa4245962 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/types.ts @@ -5,25 +5,7 @@ * 2.0. */ -import type { IconType } from '@elastic/eui'; -import { SecurityPageName } from '../../../app/types'; -import type { LinkCategories } from '../../links'; - -export type SearchNavTab = NavTab | { urlKey: UrlStateType; isDetailPage: boolean }; - -export interface NavGroupTab { - id: string; - name: string; -} -export enum SecurityNavGroupKey { - dashboards = 'dashboards', - detect = 'detect', - findings = 'findings', - explore = 'explore', - intelligence = 'intelligence', - investigate = 'investigate', - manage = 'manage', -} +import type { SecurityPageName } from '../../../app/types'; export type UrlStateType = | 'administration' @@ -48,7 +30,6 @@ export type UrlStateType = | 'entity_analytics' | 'data_quality'; -export type SecurityNavGroup = Record; export interface NavTab { id: string; name: string; @@ -61,58 +42,3 @@ export interface NavTab { text: string; }; } -export const securityNavKeys = [ - SecurityPageName.alerts, - SecurityPageName.blocklist, - SecurityPageName.detectionAndResponse, - SecurityPageName.case, - SecurityPageName.endpoints, - SecurityPageName.landing, - SecurityPageName.policies, - SecurityPageName.eventFilters, - SecurityPageName.exceptions, - SecurityPageName.hostIsolationExceptions, - SecurityPageName.hosts, - SecurityPageName.network, - SecurityPageName.overview, - SecurityPageName.responseActionsHistory, - SecurityPageName.rules, - SecurityPageName.timelines, - SecurityPageName.trustedApps, - SecurityPageName.users, - SecurityPageName.kubernetes, - SecurityPageName.threatIntelligenceIndicators, - SecurityPageName.cloudSecurityPostureDashboard, - SecurityPageName.cloudSecurityPostureFindings, - SecurityPageName.cloudSecurityPostureBenchmarks, - SecurityPageName.cloudDefendPolicies, - SecurityPageName.entityAnalytics, - SecurityPageName.dataQuality, -] as const; -export type SecurityNavKey = typeof securityNavKeys[number]; - -export type SecurityNav = Record; - -export type GenericNavRecord = Record; - -export interface SecuritySolutionTabNavigationProps { - display?: 'default' | 'condensed'; - navTabs: GenericNavRecord; -} - -export type NavigateToUrl = (url: string) => void; -export interface NavLinkItem { - categories?: LinkCategories; - description?: string; - disabled?: boolean; - icon?: IconType; - id: SecurityPageName; - links?: NavLinkItem[]; - image?: string; - title: string; - skipUrlState?: boolean; - isBeta?: boolean; - betaOptions?: { - text: string; - }; -} diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 807881811f955..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,289 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`useSecuritySolutionNavigation should create navigation config 1`] = ` -Object { - "canBeCollapsed": true, - "icon": "logoSecurity", - "items": Array [ - Object { - "id": "main", - "items": Array [ - Object { - "data-href": "securitySolutionUI/get_started", - "data-test-subj": "navigation-get_started", - "disabled": false, - "href": "securitySolutionUI/get_started", - "id": "get_started", - "isSelected": false, - "name": "Get started", - "onClick": [Function], - }, - ], - "name": "", - }, - Object { - "id": "dashboards", - "items": Array [ - Object { - "data-href": "securitySolutionUI/overview", - "data-test-subj": "navigation-overview", - "disabled": false, - "href": "securitySolutionUI/overview", - "id": "overview", - "isSelected": false, - "name": "Overview", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/detection_response", - "data-test-subj": "navigation-detection_response", - "disabled": false, - "href": "securitySolutionUI/detection_response", - "id": "detection_response", - "isSelected": false, - "name": "Detection & Response", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/cloud_security_posture-dashboard", - "data-test-subj": "navigation-cloud_security_posture-dashboard", - "disabled": false, - "href": "securitySolutionUI/cloud_security_posture-dashboard", - "id": "cloud_security_posture-dashboard", - "isSelected": false, - "name": "Cloud Security Posture", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/entity-analytics", - "data-test-subj": "navigation-entity-analytics", - "disabled": false, - "href": "securitySolutionUI/entity-analytics", - "id": "entity-analytics", - "isSelected": false, - "name": "Entity Analytics", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/data_quality", - "data-test-subj": "navigation-data_quality", - "disabled": false, - "href": "securitySolutionUI/data_quality", - "id": "data_quality", - "isSelected": false, - "name": "Data Quality", - "onClick": [Function], - }, - ], - "name": "Dashboards", - }, - Object { - "id": "detect", - "items": Array [ - Object { - "data-href": "securitySolutionUI/alerts", - "data-test-subj": "navigation-alerts", - "disabled": false, - "href": "securitySolutionUI/alerts", - "id": "alerts", - "isSelected": false, - "name": "Alerts", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/rules", - "data-test-subj": "navigation-rules", - "disabled": false, - "href": "securitySolutionUI/rules", - "id": "rules", - "isSelected": false, - "name": "Rules", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/exceptions", - "data-test-subj": "navigation-exceptions", - "disabled": false, - "href": "securitySolutionUI/exceptions", - "id": "exceptions", - "isSelected": false, - "name": "Shared Exception Lists", - "onClick": [Function], - }, - ], - "name": "Detect", - }, - Object { - "id": "findings", - "items": Array [ - Object { - "data-href": "securitySolutionUI/cloud_security_posture-findings", - "data-test-subj": "navigation-cloud_security_posture-findings", - "disabled": false, - "href": "securitySolutionUI/cloud_security_posture-findings", - "id": "cloud_security_posture-findings", - "isSelected": false, - "name": "Findings", - "onClick": [Function], - }, - ], - "name": "Findings", - }, - Object { - "id": "explore", - "items": Array [ - Object { - "data-href": "securitySolutionUI/hosts", - "data-test-subj": "navigation-hosts", - "disabled": false, - "href": "securitySolutionUI/hosts", - "id": "hosts", - "isSelected": true, - "name": "Hosts", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/network", - "data-test-subj": "navigation-network", - "disabled": false, - "href": "securitySolutionUI/network", - "id": "network", - "isSelected": false, - "name": "Network", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/users", - "data-test-subj": "navigation-users", - "disabled": false, - "href": "securitySolutionUI/users", - "id": "users", - "isSelected": false, - "name": "Users", - "onClick": [Function], - }, - ], - "name": "Explore", - }, - Object { - "id": "intelligence", - "items": Array [ - Object { - "data-href": "securitySolutionUI/threat_intelligence-indicators", - "data-test-subj": "navigation-threat_intelligence-indicators", - "disabled": false, - "href": "securitySolutionUI/threat_intelligence-indicators", - "id": "threat_intelligence-indicators", - "isSelected": false, - "name": "Indicators", - "onClick": [Function], - }, - ], - "name": "Intelligence", - }, - Object { - "id": "investigate", - "items": Array [ - Object { - "data-href": "securitySolutionUI/timelines", - "data-test-subj": "navigation-timelines", - "disabled": false, - "href": "securitySolutionUI/timelines", - "id": "timelines", - "isSelected": false, - "name": "Timelines", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/cases", - "data-test-subj": "navigation-cases", - "disabled": false, - "href": "securitySolutionUI/cases", - "id": "cases", - "isSelected": false, - "name": "Cases", - "onClick": [Function], - }, - ], - "name": "Investigate", - }, - Object { - "id": "manage", - "items": Array [ - Object { - "data-href": "securitySolutionUI/endpoints", - "data-test-subj": "navigation-endpoints", - "disabled": false, - "href": "securitySolutionUI/endpoints", - "id": "endpoints", - "isSelected": false, - "name": "Endpoints", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/trusted_apps", - "data-test-subj": "navigation-trusted_apps", - "disabled": false, - "href": "securitySolutionUI/trusted_apps", - "id": "trusted_apps", - "isSelected": false, - "name": "Trusted applications", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/event_filters", - "data-test-subj": "navigation-event_filters", - "disabled": false, - "href": "securitySolutionUI/event_filters", - "id": "event_filters", - "isSelected": false, - "name": "Event filters", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/host_isolation_exceptions", - "data-test-subj": "navigation-host_isolation_exceptions", - "disabled": false, - "href": "securitySolutionUI/host_isolation_exceptions", - "id": "host_isolation_exceptions", - "isSelected": false, - "name": "Host isolation exceptions", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/blocklist", - "data-test-subj": "navigation-blocklist", - "disabled": false, - "href": "securitySolutionUI/blocklist", - "id": "blocklist", - "isSelected": false, - "name": "Blocklist", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/response_actions_history", - "data-test-subj": "navigation-response_actions_history", - "disabled": false, - "href": "securitySolutionUI/response_actions_history", - "id": "response_actions_history", - "isSelected": false, - "name": "Response actions history", - "onClick": [Function], - }, - Object { - "data-href": "securitySolutionUI/cloud_security_posture-benchmarks", - "data-test-subj": "navigation-cloud_security_posture-benchmarks", - "disabled": false, - "href": "securitySolutionUI/cloud_security_posture-benchmarks", - "id": "cloud_security_posture-benchmarks", - "isSelected": false, - "name": "Cloud Posture Benchmarks", - "onClick": [Function], - }, - ], - "name": "Manage", - }, - ], - "name": "Security", -} -`; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx deleted file mode 100644 index dbb8d87a90e68..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx +++ /dev/null @@ -1,196 +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 { renderHook } from '@testing-library/react-hooks'; -import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; -import { useKibana } from '../../../lib/kibana/kibana_react'; -import { useGetUserCasesPermissions } from '../../../lib/kibana'; -import { SecurityPageName } from '../../../../app/types'; -import { useSecuritySolutionNavigation } from '.'; -import { useRouteSpy } from '../../../utils/route/use_route_spy'; -import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features'; -import { TestProviders } from '../../../mock'; -import { CASES_FEATURE_ID } from '../../../../../common/constants'; -import { useTourContext } from '../../guided_onboarding_tour'; -import { useUserPrivileges } from '../../user_privileges'; -import { - noCasesPermissions, - readCasesCapabilities, - readCasesPermissions, -} from '../../../../cases_test_utils'; -import { mockCasesContract } from '@kbn/cases-plugin/public/mocks'; -import { getEndpointAuthzInitialStateMock } from '../../../../../common/endpoint/service/authz/mocks'; -import { getUserPrivilegesMockDefaultValue } from '../../user_privileges/__mocks__'; - -jest.mock('../../../lib/kibana/kibana_react'); -jest.mock('../../../lib/kibana'); -const originalKibanaLib = jest.requireActual('../../../lib/kibana'); - -// Restore the useGetUserCasesPermissions so the calling functions can receive a valid permissions object -// The returned permissions object will indicate that the user does not have permissions by default -const mockUseGetUserCasesPermissions = useGetUserCasesPermissions as jest.Mock; -mockUseGetUserCasesPermissions.mockImplementation(originalKibanaLib.useGetUserCasesPermissions); - -jest.mock('../../../hooks/use_selector'); -jest.mock('../../../hooks/use_experimental_features'); -jest.mock('../../../utils/route/use_route_spy'); -jest.mock('../../guided_onboarding_tour'); -jest.mock('../../user_privileges'); - -const mockUseUserPrivileges = useUserPrivileges as jest.Mock; - -describe('useSecuritySolutionNavigation', () => { - const mockRouteSpy = [ - { - detailName: '', - flowTarget: '', - pathName: '', - search: '', - state: '', - tabName: '', - pageName: SecurityPageName.hosts, - }, - ]; - - beforeEach(() => { - (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false); - (useRouteSpy as jest.Mock).mockReturnValue(mockRouteSpy); - mockUseUserPrivileges.mockImplementation(getUserPrivilegesMockDefaultValue); - (useTourContext as jest.Mock).mockReturnValue({ isTourShown: false }); - - const cases = mockCasesContract(); - cases.helpers.getUICapabilities.mockReturnValue(readCasesPermissions()); - - (useKibana as jest.Mock).mockReturnValue({ - services: { - cases, - application: { - navigateToApp: jest.fn(), - getUrlForApp: (appId: string, options?: { path?: string; deepLinkId?: boolean }) => - `${appId}/${options?.deepLinkId ?? ''}${options?.path ?? ''}`, - capabilities: { - siem: { - show: true, - crud: true, - }, - [CASES_FEATURE_ID]: readCasesCapabilities(), - }, - }, - chrome: { - setBreadcrumbs: jest.fn(), - }, - }, - }); - }); - - afterEach(() => { - mockUseUserPrivileges.mockReset(); - }); - - it('should create navigation config', async () => { - const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>( - () => useSecuritySolutionNavigation(), - { wrapper: TestProviders } - ); - - expect(result.current).toMatchSnapshot(); - }); - - // TODO: [kubernetes] remove when no longer experimental - it('should include kubernetes when feature flag is on', async () => { - (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true); - const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>( - () => useSecuritySolutionNavigation(), - { wrapper: TestProviders } - ); - - const dashboards = result?.current?.items?.find(({ id }) => id === 'dashboards'); - const hasKubernetes = - dashboards?.items?.some(({ id }) => id === SecurityPageName.kubernetes) ?? false; - - expect(hasKubernetes).toBe(true); - }); - - it('should omit host isolation exceptions if no authz', () => { - mockUseUserPrivileges.mockImplementation(() => ({ - endpointPrivileges: getEndpointAuthzInitialStateMock({ - canReadHostIsolationExceptions: false, - }), - })); - const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>( - () => useSecuritySolutionNavigation(), - { wrapper: TestProviders } - ); - const items = result.current?.items; - expect(items).toBeDefined(); - expect( - items! - .find((item) => item.id === 'manage') - ?.items?.find((item) => item.id === 'host_isolation_exceptions') - ).toBeUndefined(); - }); - - it('should omit response actions history if hook reports false', () => { - mockUseUserPrivileges.mockImplementation(() => ({ - endpointPrivileges: getEndpointAuthzInitialStateMock({ canReadActionsLogManagement: false }), - })); - const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>( - () => useSecuritySolutionNavigation(), - { wrapper: TestProviders } - ); - const items = result.current?.items; - expect(items).toBeDefined(); - expect( - items! - .find((item) => item.id === 'manage') - ?.items?.find((item) => item.id === 'response_actions_history') - ).toBeUndefined(); - }); - - describe('Permission gated routes', () => { - describe('cases', () => { - it('should display the cases navigation item when the user has read permissions', () => { - (useGetUserCasesPermissions as jest.Mock).mockReturnValue(readCasesPermissions()); - - const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>( - () => useSecuritySolutionNavigation(), - { wrapper: TestProviders } - ); - - const caseNavItem = (result.current?.items || [])[6].items?.find( - (item) => item['data-test-subj'] === 'navigation-cases' - ); - expect(caseNavItem).toMatchInlineSnapshot(` - Object { - "data-href": "securitySolutionUI/cases", - "data-test-subj": "navigation-cases", - "disabled": false, - "href": "securitySolutionUI/cases", - "id": "cases", - "isSelected": false, - "name": "Cases", - "onClick": [Function], - } - `); - }); - - it('should not display the cases navigation item when the user does not have read permissions', () => { - (useGetUserCasesPermissions as jest.Mock).mockReturnValue(noCasesPermissions()); - - const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>( - () => useSecuritySolutionNavigation(), - { wrapper: TestProviders } - ); - - const caseNavItem = (result.current?.items || [])[3].items?.find( - (item) => item['data-test-subj'] === 'navigation-cases' - ); - expect(caseNavItem).toBeFalsy(); - }); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx index 753ce1bcb5e1c..09fc05ea9cefb 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx @@ -4,46 +4,4 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import { useEffect } from 'react'; -import { omit } from 'lodash/fp'; -import { usePrimaryNavigation } from './use_primary_navigation'; -import { useKibana } from '../../../lib/kibana'; -import { useSetBreadcrumbs } from '../breadcrumbs'; -import { useRouteSpy } from '../../../utils/route/use_route_spy'; -import { navTabs } from '../../../../app/home/home_navigations'; -import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features'; -import type { GenericNavRecord } from '../types'; - -/** - * @description - This hook provides the structure necessary by the KibanaPageTemplate for rendering the primary security_solution side navigation. - * TODO: Consolidate & re-use the logic in the hooks in this directory that are replicated from the tab_navigation to maintain breadcrumbs, telemetry, etc... - */ -export const useSecuritySolutionNavigation = () => { - const [routeProps] = useRouteSpy(); - - const { - chrome, - application: { getUrlForApp, navigateToUrl }, - } = useKibana().services; - - const disabledNavTabs = [ - ...(!useIsExperimentalFeatureEnabled('kubernetesEnabled') ? ['kubernetes'] : []), - ]; - const enabledNavTabs: GenericNavRecord = omit(disabledNavTabs, navTabs); - - const setBreadcrumbs = useSetBreadcrumbs(); - - useEffect(() => { - if (!routeProps.pathName && !routeProps.pageName) { - return; - } - - setBreadcrumbs({ ...routeProps, navTabs }, chrome, navigateToUrl); - }, [routeProps, chrome, getUrlForApp, navigateToUrl, enabledNavTabs, setBreadcrumbs]); - - return usePrimaryNavigation({ - navTabs: enabledNavTabs, - pageName: routeProps.pageName, - }); -}; +export { useSecuritySolutionNavigation } from './use_security_solution_navigation'; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/types.ts b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/types.ts deleted file mode 100644 index d4ce479fa92ed..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/types.ts +++ /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. - */ - -import type { TabNavigationProps } from '../tab_navigation/types'; -import type { GenericNavRecord } from '../types'; - -export interface PrimaryNavigationItemsProps { - navTabs: GenericNavRecord; - selectedTabId: string; -} - -export type PrimaryNavigationProps = Omit; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx deleted file mode 100644 index fb8ff7f920244..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx +++ /dev/null @@ -1,170 +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 React from 'react'; -import { useCallback, useMemo } from 'react'; -import type { EuiSideNavItemType } from '@elastic/eui/src/components/side_nav/side_nav_types'; - -import { securityNavGroup } from '../../../../app/home/home_navigations'; -import { getSearch } from '../helpers'; -import type { PrimaryNavigationItemsProps } from './types'; -import { useKibana } from '../../../lib/kibana/kibana_react'; -import { useGetUserCasesPermissions } from '../../../lib/kibana'; -import { useNavigation } from '../../../lib/kibana/hooks'; -import type { NavTab } from '../types'; -import { SecurityNavGroupKey } from '../types'; -import { SecurityPageName } from '../../../../../common/constants'; -import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features'; -import { useGlobalQueryString } from '../../../utils/global_query_string'; -import { useUserPrivileges } from '../../user_privileges'; -import { METRIC_TYPE, TELEMETRY_EVENT, track } from '../../../lib/telemetry'; - -export const usePrimaryNavigationItems = ({ - navTabs, - selectedTabId, -}: PrimaryNavigationItemsProps): Array> => { - const { navigateTo, getAppUrl } = useNavigation(); - const globalQueryString = useGlobalQueryString(); - - const getSideNav = useCallback( - (tab: NavTab) => { - const { id, name, disabled } = tab; - const isSelected = selectedTabId === id; - const urlSearch = getSearch(tab.id as SecurityPageName, globalQueryString); - - const handleClick = (ev: React.MouseEvent) => { - ev.preventDefault(); - track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.LEGACY_NAVIGATION}${id}`); - navigateTo({ deepLinkId: id, path: urlSearch }); - }; - - const appHref = getAppUrl({ deepLinkId: id, path: urlSearch }); - - return { - 'data-href': appHref, - 'data-test-subj': `navigation-${id}`, - disabled, - href: appHref, - id, - isSelected, - name, - onClick: handleClick, - }; - }, - [getAppUrl, navigateTo, selectedTabId, globalQueryString] - ); - - const navItemsToDisplay = usePrimaryNavigationItemsToDisplay(navTabs); - - return useMemo( - () => - navItemsToDisplay.map((item) => ({ - ...item, - items: item.items.map((t: NavTab) => getSideNav(t)), - })), - [getSideNav, navItemsToDisplay] - ); -}; - -function usePrimaryNavigationItemsToDisplay(navTabs: Record) { - const hasCasesReadPermissions = useGetUserCasesPermissions().read; - const { canReadActionsLogManagement, canReadHostIsolationExceptions } = - useUserPrivileges().endpointPrivileges; - const isPolicyListEnabled = useIsExperimentalFeatureEnabled('policyListEnabled'); - - const uiCapabilities = useKibana().services.application.capabilities; - return useMemo( - () => - uiCapabilities.siem.show - ? [ - { - id: 'main', - name: '', - items: [navTabs[SecurityPageName.landing]], - }, - { - ...securityNavGroup[SecurityNavGroupKey.dashboards], - items: [ - navTabs[SecurityPageName.overview], - navTabs[SecurityPageName.detectionAndResponse], - navTabs[SecurityPageName.cloudSecurityPostureDashboard], - navTabs[SecurityPageName.entityAnalytics], - navTabs[SecurityPageName.dataQuality], - ...(navTabs[SecurityPageName.kubernetes] != null - ? [navTabs[SecurityPageName.kubernetes]] - : []), - ], - }, - { - ...securityNavGroup[SecurityNavGroupKey.detect], - items: [ - navTabs[SecurityPageName.alerts], - navTabs[SecurityPageName.rules], - navTabs[SecurityPageName.exceptions], - ], - }, - { - ...securityNavGroup[SecurityNavGroupKey.findings], - items: [navTabs[SecurityPageName.cloudSecurityPostureFindings]], - }, - { - ...securityNavGroup[SecurityNavGroupKey.explore], - items: [ - navTabs[SecurityPageName.hosts], - navTabs[SecurityPageName.network], - ...(navTabs[SecurityPageName.users] != null - ? [navTabs[SecurityPageName.users]] - : []), - ], - }, - { - ...securityNavGroup[SecurityNavGroupKey.intelligence], - items: [navTabs[SecurityPageName.threatIntelligenceIndicators]], - }, - { - ...securityNavGroup[SecurityNavGroupKey.investigate], - items: hasCasesReadPermissions - ? [navTabs[SecurityPageName.timelines], navTabs[SecurityPageName.case]] - : [navTabs[SecurityPageName.timelines]], - }, - { - ...securityNavGroup[SecurityNavGroupKey.manage], - items: [ - // TODO: also hide other management pages based on authz privileges - navTabs[SecurityPageName.endpoints], - ...(isPolicyListEnabled ? [navTabs[SecurityPageName.policies]] : []), - navTabs[SecurityPageName.trustedApps], - navTabs[SecurityPageName.eventFilters], - ...(canReadHostIsolationExceptions - ? [navTabs[SecurityPageName.hostIsolationExceptions]] - : []), - navTabs[SecurityPageName.blocklist], - ...(canReadActionsLogManagement - ? [navTabs[SecurityPageName.responseActionsHistory]] - : []), - navTabs[SecurityPageName.cloudSecurityPostureBenchmarks], - ], - }, - ] - : hasCasesReadPermissions - ? [ - { - ...securityNavGroup[SecurityNavGroupKey.investigate], - items: [navTabs[SecurityPageName.case]], - }, - ] - : [], - [ - uiCapabilities.siem.show, - navTabs, - hasCasesReadPermissions, - canReadHostIsolationExceptions, - canReadActionsLogManagement, - isPolicyListEnabled, - ] - ); -} diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx deleted file mode 100644 index 867cda2bcf4e8..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect, useState, useCallback } from 'react'; -import { i18n } from '@kbn/i18n'; - -import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; -import useObservable from 'react-use/lib/useObservable'; -import type { PrimaryNavigationProps } from './types'; -import { usePrimaryNavigationItems } from './use_navigation_items'; -import { useIsGroupedNavigationEnabled } from '../helpers'; -import { SecuritySideNav } from '../security_side_nav'; -import { useKibana } from '../../../lib/kibana'; - -const translatedNavTitle = i18n.translate('xpack.securitySolution.navigation.mainLabel', { - defaultMessage: 'Security', -}); - -export const usePrimaryNavigation = ({ - navTabs, - pageName, -}: PrimaryNavigationProps): KibanaPageTemplateProps['solutionNav'] => { - const isGroupedNavigationEnabled = useIsGroupedNavigationEnabled(); - const mapLocationToTab = useCallback( - (): string => navTabs[pageName]?.id ?? '', - [pageName, navTabs] - ); - - const [selectedTabId, setSelectedTabId] = useState(mapLocationToTab()); - - useEffect(() => { - const currentTabSelected = mapLocationToTab(); - - if (currentTabSelected !== selectedTabId) { - setSelectedTabId(currentTabSelected); - } - - // we do need navTabs in case the selectedTabId appears after initial load (ex. checking permissions for anomalies) - }, [pageName, navTabs, mapLocationToTab, selectedTabId]); - - const navItems = usePrimaryNavigationItems({ - navTabs, - selectedTabId, - }); - - const { isSidebarEnabled$ } = useKibana().services; - - const isSidebarEnabled = useObservable(isSidebarEnabled$); - - if (!isSidebarEnabled) { - return undefined; - } - - return { - canBeCollapsed: true, - name: translatedNavTitle, - icon: 'logoSecurity', - ...(isGroupedNavigationEnabled - ? { - children: , - closeFlyoutButtonPosition: 'inside', - } - : { items: navItems }), - }; -}; 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 new file mode 100644 index 0000000000000..42f46525bdbe4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.test.tsx @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { 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, +})); + +const mockIsSidebarEnabled$ = new BehaviorSubject(true); +jest.mock('../../../lib/kibana/kibana_react', () => { + return { + useKibana: () => ({ + services: { + isSidebarEnabled$: mockIsSidebarEnabled$.asObservable(), + }, + }), + }; +}); + +describe('Security Solution Navigation', () => { + beforeEach(() => { + mockIsSidebarEnabled$.next(true); + jest.clearAllMocks(); + }); + + it('should return proper navigation props', () => { + const { result } = renderHook(useSecuritySolutionNavigation); + expect(result.current).toEqual( + expect.objectContaining({ + canBeCollapsed: true, + name: 'Security', + icon: 'logoSecurity', + closeFlyoutButtonPosition: 'inside', + }) + ); + expect(result.current?.children).toBeDefined(); + }); + + it('should return undefined props when disabled', () => { + mockIsSidebarEnabled$.next(false); + const { result } = renderHook(useSecuritySolutionNavigation); + expect(result.current).toEqual(undefined); + }); +}); 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 new file mode 100644 index 0000000000000..bf4e8359cb464 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_security_solution_navigation.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 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 { SecuritySideNav } from '../security_side_nav'; + +const translatedNavTitle = i18n.translate('xpack.securitySolution.navigation.mainLabel', { + defaultMessage: 'Security', +}); + +export const useSecuritySolutionNavigation = (): KibanaPageTemplateProps['solutionNav'] => { + const { isSidebarEnabled$ } = useKibana().services; + const isSidebarEnabled = useObservable(isSidebarEnabled$); + + useBreadcrumbs({ + isEnabled: true, // TODO: use isSidebarEnabled$ when serverless breadcrumb is ready + }); + + if (!isSidebarEnabled) { + return undefined; + } + + return { + canBeCollapsed: true, + name: translatedNavTitle, + icon: 'logoSecurity', + children: , + closeFlyoutButtonPosition: 'inside', + }; +}; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.test.ts b/x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.test.ts deleted file mode 100644 index 38a0b7e25baae..0000000000000 --- a/x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.test.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 { navTabs } from '../../app/home/home_navigations'; -import { getTitle } from './use_update_browser_title'; - -describe('Helpers Url_State', () => { - describe('getTitle', () => { - test('host page name', () => { - const result = getTitle('hosts', navTabs); - expect(result).toEqual('Hosts'); - }); - test('network page name', () => { - const result = getTitle('network', navTabs); - expect(result).toEqual('Network'); - }); - test('overview page name', () => { - const result = getTitle('overview', navTabs); - expect(result).toEqual('Overview'); - }); - test('timelines page name', () => { - const result = getTitle('timelines', navTabs); - expect(result).toEqual('Timelines'); - }); - test('Not existing', () => { - const result = getTitle('IamHereButNotReally', navTabs); - expect(result).toEqual(''); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.ts b/x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.ts index 27b43b43bd705..9dc10d69a05eb 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_update_browser_title.ts @@ -6,26 +6,14 @@ */ import { useEffect } from 'react'; -import { navTabs } from '../../app/home/home_navigations'; -import { useIsGroupedNavigationEnabled } from '../components/navigation/helpers'; -import type { NavTab } from '../components/navigation/types'; import { getLinkInfo } from '../links'; import { useRouteSpy } from '../utils/route/use_route_spy'; export const useUpdateBrowserTitle = () => { - const isGroupedNavEnabled = useIsGroupedNavigationEnabled(); const [{ pageName }] = useRouteSpy(); const linkInfo = getLinkInfo(pageName); useEffect(() => { - if (!isGroupedNavEnabled) { - document.title = `${getTitle(pageName, navTabs)} - Kibana`; - } else { - document.title = `${linkInfo?.title ?? ''} - Kibana`; - } - }, [pageName, isGroupedNavEnabled, linkInfo]); -}; - -export const getTitle = (pageName: string, tabs: Record): string => { - return tabs[pageName] != null ? tabs[pageName].name : ''; + document.title = `${linkInfo?.title ?? ''} - Kibana`; + }, [pageName, linkInfo]); }; diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/index.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/index.ts index 5158ac09c50e7..1f6fcaca3f7c8 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/index.ts @@ -68,7 +68,6 @@ export enum TELEMETRY_EVENT { // Breadcrumbs BREADCRUMB = 'breadcrumb_', - LEGACY_NAVIGATION = 'legacy_navigation_', } export const getTelemetryEvent = { diff --git a/x-pack/plugins/security_solution/public/common/links/deep_links.ts b/x-pack/plugins/security_solution/public/common/links/deep_links.ts new file mode 100644 index 0000000000000..c8b38042ddd7e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/links/deep_links.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 type { Subject, Subscription } from 'rxjs'; +import { AppNavLinkStatus } from '@kbn/core/public'; +import type { AppDeepLink, AppUpdater } from '@kbn/core/public'; +import { appLinks$ } from './links'; +import type { AppLinkItems } from './types'; + +const formatDeepLinks = (appLinks: AppLinkItems): AppDeepLink[] => + appLinks.map((appLink) => ({ + id: appLink.id, + path: appLink.path, + title: appLink.title, + searchable: !appLink.globalSearchDisabled, + ...(appLink.globalNavPosition != null + ? { navLinkStatus: AppNavLinkStatus.visible, order: appLink.globalNavPosition } + : { navLinkStatus: AppNavLinkStatus.hidden }), + ...(appLink.globalSearchKeywords != null ? { keywords: appLink.globalSearchKeywords } : {}), + ...(appLink.links && appLink.links?.length + ? { + deepLinks: formatDeepLinks(appLink.links), + } + : {}), + })); + +/** + * Registers any change in appLinks to be updated in app deepLinks + */ +export const registerDeepLinksUpdater = (appUpdater$: Subject): Subscription => { + return appLinks$.subscribe((appLinks) => { + appUpdater$.next(() => ({ + navLinkStatus: AppNavLinkStatus.hidden, // needed to prevent main security link to switch to visible after update + deepLinks: formatDeepLinks(appLinks), + })); + }); +}; diff --git a/x-pack/plugins/security_solution/public/common/links/links.ts b/x-pack/plugins/security_solution/public/common/links/links.ts index be1f206e339b2..a1e5cf37831fe 100644 --- a/x-pack/plugins/security_solution/public/common/links/links.ts +++ b/x-pack/plugins/security_solution/public/common/links/links.ts @@ -6,7 +6,7 @@ */ import type { Capabilities } from '@kbn/core/public'; -import { get, isArray } from 'lodash'; +import get from 'lodash/get'; import { useMemo } from 'react'; import useObservable from 'react-use/lib/useObservable'; import { BehaviorSubject } from 'rxjs'; @@ -169,11 +169,11 @@ export const hasCapabilities = ( linkCapabilities: LinkCapabilities, userCapabilities: Capabilities ): boolean => { - if (!isArray(linkCapabilities)) { + if (!Array.isArray(linkCapabilities)) { return !!get(userCapabilities, linkCapabilities, false); } else { return linkCapabilities.some((linkCapabilityKeyOr) => { - if (isArray(linkCapabilityKeyOr)) { + if (Array.isArray(linkCapabilityKeyOr)) { return linkCapabilityKeyOr.every((linkCapabilityKeyAnd) => get(userCapabilities, linkCapabilityKeyAnd, false) ); diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx index 253c16a044f04..d8e572a7bb119 100644 --- a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx @@ -12,7 +12,6 @@ import { createMemoryHistory } from 'history'; import type { RenderOptions, RenderResult } from '@testing-library/react'; import { render as reactRender } from '@testing-library/react'; import type { Action, Reducer, Store } from 'redux'; -import type { AppDeepLink } from '@kbn/core/public'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { coreMock } from '@kbn/core/public/mocks'; import { PLUGIN_ID } from '@kbn/fleet-plugin/common'; @@ -24,6 +23,7 @@ import type { } from '@testing-library/react-hooks/src/types/react'; import type { UseBaseQueryResult } from '@tanstack/react-query'; import ReactDOM from 'react-dom'; +import type { AppLinkItems } from '../../links/types'; import { ExperimentalFeaturesService } from '../../experimental_features_service'; import { applyIntersectionObserverMock } from '../intersection_observer_mock'; import { ConsoleManager } from '../../../management/components/console'; @@ -41,7 +41,7 @@ import { SUB_PLUGINS_REDUCER, mockGlobalState, createSecuritySolutionStorageMock import type { ExperimentalFeatures } from '../../../../common/experimental_features'; import { APP_UI_ID, APP_PATH } from '../../../../common/constants'; import { KibanaContextProvider, KibanaServices } from '../../lib/kibana'; -import { getDeepLinks } from '../../../app/deep_links'; +import { links } from '../../links/app_links'; import { fleetGetPackageHttpMock } from '../../../management/mocks'; import { allowedExperimentalValues } from '../../../../common/experimental_features'; @@ -339,7 +339,7 @@ const createCoreStartMock = ( ): ReturnType => { const coreStart = coreMock.createStart({ basePath: '/mock' }); - const deepLinkPaths = getDeepLinkPaths(getDeepLinks(mockGlobalState.app.enableExperimental)); + const linkPaths = getLinksPaths(links); // Mock the certain APP Ids returned by `application.getUrlForApp()` coreStart.application.getUrlForApp.mockImplementation((appId, { deepLinkId, path } = {}) => { @@ -347,9 +347,9 @@ const createCoreStartMock = ( case PLUGIN_ID: return '/app/fleet'; case APP_UI_ID: - return `${APP_PATH}${ - deepLinkId && deepLinkPaths[deepLinkId] ? deepLinkPaths[deepLinkId] : '' - }${path ?? ''}`; + return `${APP_PATH}${deepLinkId && linkPaths[deepLinkId] ? linkPaths[deepLinkId] : ''}${ + path ?? '' + }`; default: return `${appId} not mocked!`; } @@ -358,7 +358,7 @@ const createCoreStartMock = ( coreStart.application.navigateToApp.mockImplementation((appId, { deepLinkId, path } = {}) => { if (appId === APP_UI_ID) { history.push( - `${deepLinkId && deepLinkPaths[deepLinkId] ? deepLinkPaths[deepLinkId] : ''}${path ?? ''}` + `${deepLinkId && linkPaths[deepLinkId] ? linkPaths[deepLinkId] : ''}${path ?? ''}` ); } return Promise.resolve(); @@ -372,13 +372,13 @@ const createCoreStartMock = ( return coreStart; }; -const getDeepLinkPaths = (deepLinks: AppDeepLink[]): Record => { - return deepLinks.reduce((result: Record, deepLink) => { - if (deepLink.path) { - result[deepLink.id] = deepLink.path; +const getLinksPaths = (appLinks: AppLinkItems): Record => { + return appLinks.reduce((result: Record, link) => { + if (link.path) { + result[link.id] = link.path; } - if (deepLink.deepLinks) { - return { ...result, ...getDeepLinkPaths(deepLink.deepLinks) }; + if (link.links) { + return { ...result, ...getLinksPaths(link.links) }; } return result; }, {}); diff --git a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.test.tsx b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.test.tsx index f19e98020fce8..71933ab00ad0f 100644 --- a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.test.tsx +++ b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.test.tsx @@ -30,11 +30,6 @@ jest.mock('../../containers/sourcerer', () => ({ useSourcererDataView: () => mockUseSourcererDataView(), })); -const mockedUseIsGroupedNavigationEnabled = jest.fn(); -jest.mock('../../components/navigation/helpers', () => ({ - useIsGroupedNavigationEnabled: () => mockedUseIsGroupedNavigationEnabled(), -})); - const mockSiemUserCanRead = jest.fn(() => true); jest.mock('../../lib/kibana', () => { const original = jest.requireActual('../../lib/kibana'); @@ -73,123 +68,75 @@ describe('use show timeline', () => { }, }); }); - describe('useIsGroupedNavigationEnabled false', () => { - beforeAll(() => { - mockedUseIsGroupedNavigationEnabled.mockReturnValue(false); - }); - it('shows timeline for routes on default', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([true]); - }); - }); - - it('hides timeline for blacklist routes', async () => { - mockUseLocation.mockReturnValueOnce({ pathname: '/rules/create' }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([false]); - }); - }); - it('shows timeline for partial blacklist routes', async () => { - mockUseLocation.mockReturnValueOnce({ pathname: '/rules' }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([true]); - }); - }); - it('hides timeline for sub blacklist routes', async () => { - mockUseLocation.mockReturnValueOnce({ pathname: '/administration/policy' }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([false]); - }); + it('shows timeline for routes on default', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); + await waitForNextUpdate(); + const showTimeline = result.current; + expect(showTimeline).toEqual([true]); }); }); - describe('useIsGroupedNavigationEnabled true', () => { - beforeAll(() => { - mockedUseIsGroupedNavigationEnabled.mockReturnValue(true); - }); - - it('shows timeline for routes on default', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([true]); - }); + it('hides timeline for blacklist routes', async () => { + mockUseLocation.mockReturnValueOnce({ pathname: '/rules/create' }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); + await waitForNextUpdate(); + const showTimeline = result.current; + expect(showTimeline).toEqual([false]); }); - - it('hides timeline for blacklist routes', async () => { - mockUseLocation.mockReturnValueOnce({ pathname: '/rules/create' }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([false]); - }); - }); - it('shows timeline for partial blacklist routes', async () => { - mockUseLocation.mockReturnValueOnce({ pathname: '/rules' }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([true]); - }); + }); + it('shows timeline for partial blacklist routes', async () => { + mockUseLocation.mockReturnValueOnce({ pathname: '/rules' }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); + await waitForNextUpdate(); + const showTimeline = result.current; + expect(showTimeline).toEqual([true]); }); - it('hides timeline for sub blacklist routes', async () => { - mockUseLocation.mockReturnValueOnce({ pathname: '/administration/policy' }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); - await waitForNextUpdate(); - const showTimeline = result.current; - expect(showTimeline).toEqual([false]); - }); + }); + it('hides timeline for sub blacklist routes', async () => { + mockUseLocation.mockReturnValueOnce({ pathname: '/administration/policy' }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); + await waitForNextUpdate(); + const showTimeline = result.current; + expect(showTimeline).toEqual([false]); }); }); +}); - describe('sourcererDataView', () => { - it('should show timeline when indices exist', () => { - mockUseSourcererDataView.mockReturnValueOnce({ indicesExist: true, dataViewId: 'test' }); - const { result } = renderHook(() => useShowTimeline()); - expect(result.current).toEqual([true]); - }); +describe('sourcererDataView', () => { + it('should show timeline when indices exist', () => { + mockUseSourcererDataView.mockReturnValueOnce({ indicesExist: true, dataViewId: 'test' }); + const { result } = renderHook(() => useShowTimeline()); + expect(result.current).toEqual([true]); + }); - it('should show timeline when dataViewId is null', () => { - mockUseSourcererDataView.mockReturnValueOnce({ indicesExist: false, dataViewId: null }); - const { result } = renderHook(() => useShowTimeline()); - expect(result.current).toEqual([true]); - }); + it('should show timeline when dataViewId is null', () => { + mockUseSourcererDataView.mockReturnValueOnce({ indicesExist: false, dataViewId: null }); + const { result } = renderHook(() => useShowTimeline()); + expect(result.current).toEqual([true]); + }); - it('should not show timeline when dataViewId is not null and indices does not exist', () => { - mockUseSourcererDataView.mockReturnValueOnce({ indicesExist: false, dataViewId: 'test' }); - const { result } = renderHook(() => useShowTimeline()); - expect(result.current).toEqual([false]); - }); + it('should not show timeline when dataViewId is not null and indices does not exist', () => { + mockUseSourcererDataView.mockReturnValueOnce({ indicesExist: false, dataViewId: 'test' }); + const { result } = renderHook(() => useShowTimeline()); + expect(result.current).toEqual([false]); }); +}); - describe('Security solution capabilities', () => { - it('should show timeline when user has read capabilities', () => { - mockSiemUserCanRead.mockReturnValueOnce(true); - const { result } = renderHook(() => useShowTimeline()); - expect(result.current).toEqual([true]); - }); +describe('Security solution capabilities', () => { + it('should show timeline when user has read capabilities', () => { + mockSiemUserCanRead.mockReturnValueOnce(true); + const { result } = renderHook(() => useShowTimeline()); + expect(result.current).toEqual([true]); + }); - it('should not show timeline when user does not have read capabilities', () => { - mockSiemUserCanRead.mockReturnValueOnce(false); - const { result } = renderHook(() => useShowTimeline()); - expect(result.current).toEqual([false]); - }); + it('should not show timeline when user does not have read capabilities', () => { + mockSiemUserCanRead.mockReturnValueOnce(false); + const { result } = renderHook(() => useShowTimeline()); + expect(result.current).toEqual([false]); }); }); diff --git a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline_for_path.ts b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline_for_path.ts index a06f6b5ab0e4f..233194332754b 100644 --- a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline_for_path.ts +++ b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline_for_path.ts @@ -9,38 +9,17 @@ import { useCallback, useMemo } from 'react'; import { matchPath } from 'react-router-dom'; import { getLinksWithHiddenTimeline } from '../../links'; -import { useIsGroupedNavigationEnabled } from '../../components/navigation/helpers'; import { SourcererScopeName } from '../../store/sourcerer/model'; import { useSourcererDataView } from '../../containers/sourcerer'; import { useKibana } from '../../lib/kibana'; -const DEPRECATED_HIDDEN_TIMELINE_ROUTES: readonly string[] = [ - `/cases/configure`, - '/administration', - '/rules/create', - '/get_started', - '/explore', - '/dashboards', - '/manage', - '/cloud_security_posture*', -]; - -const isTimelinePathVisible = ( - currentPath: string, - isGroupedNavigationEnabled: boolean -): boolean => { +const isTimelinePathVisible = (currentPath: string): boolean => { const groupLinksWithHiddenTimelinePaths = getLinksWithHiddenTimeline().map((l) => l.path); - - const hiddenTimelineRoutes = isGroupedNavigationEnabled - ? groupLinksWithHiddenTimelinePaths - : DEPRECATED_HIDDEN_TIMELINE_ROUTES; - + const hiddenTimelineRoutes = groupLinksWithHiddenTimelinePaths; return !hiddenTimelineRoutes.find((route) => matchPath(currentPath, route)); }; export const useShowTimelineForGivenPath = () => { - const isGroupedNavigationEnabled = useIsGroupedNavigationEnabled(); - const { indicesExist, dataViewId } = useSourcererDataView(SourcererScopeName.timeline); const userHasSecuritySolutionVisible = useKibana().services.application.capabilities.siem.show; @@ -54,9 +33,9 @@ export const useShowTimelineForGivenPath = () => { if (!isTimelineAllowed) { return false; } - return isTimelinePathVisible(pathname, isGroupedNavigationEnabled); + return isTimelinePathVisible(pathname); }, - [isTimelineAllowed, isGroupedNavigationEnabled] + [isTimelineAllowed] ); return getIsTimelineVisible; diff --git a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx index fa12b78af2991..62ab44f7aa9c7 100644 --- a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { SecurityPageName } from '../../../app/types'; import { TestProviders } from '../../../common/mock'; import { DashboardsLandingPage } from '.'; -import type { NavLinkItem } from '../../../common/components/navigation/types'; +import type { NavigationLink } from '../../../common/links'; import { useCapabilities } from '../../../common/lib/kibana'; import * as telemetry from '../../../common/lib/telemetry'; @@ -28,7 +28,7 @@ const spyTrack = jest.spyOn(telemetry, 'track'); const OVERVIEW_ITEM_LABEL = 'Overview'; const DETECTION_RESPONSE_ITEM_LABEL = 'Detection & Response'; -const APP_DASHBOARD_LINKS: NavLinkItem = { +const APP_DASHBOARD_LINKS: NavigationLink = { id: SecurityPageName.dashboards, title: 'Dashboards', links: [ diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index b0e739a17a1c8..22a458a82eca3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -44,7 +44,7 @@ import { AlertsTableComponent } from '../../../../detections/components/alerts_t import { GroupedAlertsTable } from '../../../../detections/components/alerts_table/alerts_grouping'; import { useDataTableFilters } from '../../../../common/hooks/use_data_table_filters'; import { isMlRule } from '../../../../../common/machine_learning/helpers'; -import { TabNavigationWithBreadcrumbs } from '../../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../../common/components/navigation/tab_navigation'; import { InputsModelId } from '../../../../common/store/inputs/constants'; import { useDeepEqualSelector, @@ -820,7 +820,7 @@ const RuleDetailsPageComponent: React.FC = ({
- + diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx index 562177371de58..bacdced332c58 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx @@ -6,7 +6,7 @@ */ import React, { useMemo } from 'react'; -import { TabNavigationWithBreadcrumbs } from '../../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../../common/components/navigation/tab_navigation'; import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; export enum AllRulesTabs { @@ -33,7 +33,7 @@ export const RulesTableToolbar = React.memo(() => { [] ); - return ; + return ; }); RulesTableToolbar.displayName = 'RulesTableToolbar'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx index c95cb3a7f03eb..0fa0e128c3b11 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx @@ -19,7 +19,7 @@ import { SourcererScopeName } from '../../../common/store/sourcerer/model'; import { SpyRoute } from '../../../common/utils/route/spy_routes'; import { getAlertDetailsTabUrl } from '../../../common/components/link_to'; import { AlertDetailRouteType } from './types'; -import { TabNavigationWithBreadcrumbs } from '../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../common/components/navigation/tab_navigation'; import { getAlertDetailsNavTabs } from './utils/navigation'; import { SecurityPageName } from '../../../../common/constants'; import { eventID } from '../../../../common/endpoint/models/event'; @@ -73,7 +73,7 @@ export const AlertDetailsPage = memo(() => { {hasData && ( <> - + 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 8fcfa03624f8a..107cdb8af4de6 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 @@ -35,7 +35,7 @@ import { hostToCriteria } from '../../../../common/components/ml/criteria/host_t import { hasMlUserPermissions } from '../../../../../common/machine_learning/has_ml_user_permissions'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; import { scoreIntervalToDateTime } from '../../../../common/components/ml/score/score_interval_to_datetime'; -import { TabNavigationWithBreadcrumbs } from '../../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../../common/components/navigation/tab_navigation'; import { HostOverview } from '../../../../overview/components/host_overview'; import { SiemSearchBar } from '../../../../common/components/search_bar'; import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; @@ -249,7 +249,7 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta )} - { ); - expect(wrapper.find(TabNavigationWithBreadcrumbs).exists()).toBe(true); + expect(wrapper.find(TabNavigation).exists()).toBe(true); }); test('it should add the new filters after init', async () => { diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.tsx index d35e443916cd1..f5bd164510316 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/hosts.tsx @@ -22,7 +22,7 @@ import { FiltersGlobal } from '../../../common/components/filters_global'; import { HeaderPage } from '../../../common/components/header_page'; import { LastEventTime } from '../../../common/components/last_event_time'; import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; -import { TabNavigationWithBreadcrumbs } from '../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../common/components/navigation/tab_navigation'; import { HostsKpiComponent } from '../components/kpi_hosts'; import { SiemSearchBar } from '../../../common/components/search_bar'; import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; @@ -212,7 +212,7 @@ const HostsComponent = () => { - { )} - diff --git a/x-pack/plugins/security_solution/public/explore/network/pages/network.tsx b/x-pack/plugins/security_solution/public/explore/network/pages/network.tsx index 4ff83f07c2ccb..fbc45396712ac 100644 --- a/x-pack/plugins/security_solution/public/explore/network/pages/network.tsx +++ b/x-pack/plugins/security_solution/public/explore/network/pages/network.tsx @@ -22,7 +22,7 @@ import { EmbeddedMap } from '../components/embeddables/embedded_map'; import { FiltersGlobal } from '../../../common/components/filters_global'; import { HeaderPage } from '../../../common/components/header_page'; import { LastEventTime } from '../../../common/components/last_event_time'; -import { TabNavigationWithBreadcrumbs } from '../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../common/components/navigation/tab_navigation'; import { NetworkKpiComponent } from '../components/kpi_network'; import { SiemSearchBar } from '../../../common/components/search_bar'; @@ -207,7 +207,7 @@ const NetworkComponent = React.memo( <> - + 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 10581694bc36f..0046d9aa6f61f 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 @@ -27,7 +27,7 @@ import { InputsModelId } from '../../../../common/store/inputs/constants'; import { SecurityPageName } from '../../../../app/types'; import { FiltersGlobal } from '../../../../common/components/filters_global'; import { HeaderPage } from '../../../../common/components/header_page'; -import { TabNavigationWithBreadcrumbs } from '../../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../../common/components/navigation/tab_navigation'; import { SiemSearchBar } from '../../../../common/components/search_bar'; import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; @@ -238,7 +238,7 @@ const UsersDetailsComponent: React.FC = ({ )} - { - + diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx index 23aa058e62311..4c83fb56594b4 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.test.tsx @@ -11,7 +11,7 @@ import { Router } from 'react-router-dom'; import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; -import { TabNavigationWithBreadcrumbs } from '../../../common/components/navigation/tab_navigation_with_breadcrumbs'; +import { TabNavigation } from '../../../common/components/navigation/tab_navigation'; import { Users } from './users'; import { useSourcererDataView } from '../../../common/containers/sourcerer'; import { mockCasesContext } from '@kbn/cases-plugin/public/mocks/mock_cases_context'; @@ -100,6 +100,6 @@ describe('Users - rendering', () => { ); - expect(wrapper.find(TabNavigationWithBreadcrumbs).exists()).toBe(true); + expect(wrapper.find(TabNavigation).exists()).toBe(true); }); }); diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 7116b278f81ff..ec2ec5a6fef18 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -6,9 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import type { Subscription } from 'rxjs'; import { BehaviorSubject, Subject } from 'rxjs'; -import { combineLatestWith } from 'rxjs/operators'; import type * as H from 'history'; import type { AppMountParameters, @@ -35,17 +33,10 @@ import { initTelemetry, TelemetryService } from './common/lib/telemetry'; import { KibanaServices } from './common/lib/kibana/services'; import { SOLUTION_NAME } from './common/translations'; -import { - APP_ID, - APP_UI_ID, - APP_PATH, - APP_ICON_SOLUTION, - ENABLE_GROUPED_NAVIGATION, -} from '../common/constants'; - -import { getDeepLinks, registerDeepLinksUpdater } from './app/deep_links'; -import type { LinksPermissions } from './common/links'; -import { updateAppLinks } from './common/links'; +import { APP_ID, APP_UI_ID, APP_PATH, APP_ICON_SOLUTION } from '../common/constants'; + +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'; @@ -493,12 +484,11 @@ export class Plugin implements IPlugin(ENABLE_GROUPED_NAVIGATION, true); - let appLinksSubscription: Subscription | null = null; - license$.pipe(combineLatestWith(newNavEnabled$)).subscribe(async ([license, newNavEnabled]) => { + registerDeepLinksUpdater(this.appUpdater$); + + license$.subscribe(async (license) => { const linksPermissions: LinksPermissions = { experimentalFeatures: this.experimentalFeatures, capabilities: core.application.capabilities, @@ -508,25 +498,6 @@ export class Plugin implements IPlugin ({ - navLinkStatus: AppNavLinkStatus.hidden, - deepLinks: getDeepLinks( - this.experimentalFeatures, - license.type, - core.application.capabilities - ), - })); - } - // set initial links to not block rendering updateAppLinks(links, linksPermissions); diff --git a/x-pack/plugins/security_solution/server/ui_settings.ts b/x-pack/plugins/security_solution/server/ui_settings.ts index 4b8fe1be50ec0..935b383268513 100644 --- a/x-pack/plugins/security_solution/server/ui_settings.ts +++ b/x-pack/plugins/security_solution/server/ui_settings.ts @@ -25,7 +25,6 @@ import { DEFAULT_THREAT_INDEX_KEY, DEFAULT_THREAT_INDEX_VALUE, DEFAULT_TO, - ENABLE_GROUPED_NAVIGATION, ENABLE_NEWS_FEED_SETTING, IP_REPUTATION_LINKS_SETTING, IP_REPUTATION_LINKS_SETTING_DEFAULT, @@ -149,23 +148,6 @@ export const initUiSettings = ( requiresPageReload: true, schema: schema.number(), }, - [ENABLE_GROUPED_NAVIGATION]: { - name: i18n.translate('xpack.securitySolution.uiSettings.enableGroupedNavigation', { - defaultMessage: 'New streamlined navigation', - }), - value: true, - type: 'boolean', - description: i18n.translate( - 'xpack.securitySolution.uiSettings.enableGroupedNavigationDescription', - { - defaultMessage: - '

Improve your experience with the new navigation organized and optimized around the most important workflows.

', - } - ), - category: [APP_ID], - requiresPageReload: false, - schema: schema.boolean(), - }, [ENABLE_NEWS_FEED_SETTING]: { name: i18n.translate('xpack.securitySolution.uiSettings.enableNewsFeedLabel', { defaultMessage: 'News feed', diff --git a/x-pack/plugins/threat_intelligence/public/index.ts b/x-pack/plugins/threat_intelligence/public/index.ts index 702af6050fbd3..534142a5acef9 100755 --- a/x-pack/plugins/threat_intelligence/public/index.ts +++ b/x-pack/plugins/threat_intelligence/public/index.ts @@ -11,11 +11,7 @@ export { THREAT_INTELLIGENCE_BASE_PATH } from './constants/navigation'; export type { TIPageId } from './types'; -export { - getSecuritySolutionDeepLink, - getSecuritySolutionLink, - getSecuritySolutionNavTab, -} from './utils/security_solution_links'; +export { getSecuritySolutionLink } from './utils/security_solution_links'; export function plugin() { return new ThreatIntelligencePlugin(); diff --git a/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.test.ts b/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.test.ts index 9eb94beef9a29..92aceb9da6736 100644 --- a/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.test.ts +++ b/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.test.ts @@ -6,24 +6,7 @@ */ import { threatIntelligencePages } from '../constants/navigation'; -import { - getSecuritySolutionDeepLink, - getSecuritySolutionLink, - getSecuritySolutionNavTab, -} from './security_solution_links'; - -describe('getSecuritySolutionDeepLink', () => { - it('gets the correct deeplink properties', () => { - const threatIntelligencePage = 'indicators'; - - const link = getSecuritySolutionDeepLink(threatIntelligencePage); - - expect(link.id).toEqual(threatIntelligencePages[threatIntelligencePage].id); - expect(link.keywords).toEqual(threatIntelligencePages[threatIntelligencePage].keywords); - expect(link.path).toEqual(threatIntelligencePages[threatIntelligencePage].path); - expect(link.title).toEqual(threatIntelligencePages[threatIntelligencePage].newNavigationName); - }); -}); +import { getSecuritySolutionLink } from './security_solution_links'; describe('getSecuritySolutionLink', () => { it('gets the correct link properties', () => { @@ -40,19 +23,3 @@ describe('getSecuritySolutionLink', () => { expect(link.title).toEqual(threatIntelligencePages[threatIntelligencePage].newNavigationName); }); }); - -describe('getSecuritySolutionNavTab', () => { - it('gets the correct navtab properties', () => { - const threatIntelligencePage = 'indicators'; - const basePath = 'threat_intelligence/'; - - const navTab = getSecuritySolutionNavTab(threatIntelligencePage, basePath); - - expect(navTab.disabled).toEqual(threatIntelligencePages[threatIntelligencePage].disabled); - expect(navTab.href).toEqual( - `${basePath}${threatIntelligencePages[threatIntelligencePage].path}` - ); - expect(navTab.id).toEqual(threatIntelligencePages[threatIntelligencePage].id); - expect(navTab.name).toEqual(threatIntelligencePages[threatIntelligencePage].oldNavigationName); - }); -}); diff --git a/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts b/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts index f79452ac2d8dd..87d7c7239d533 100644 --- a/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts +++ b/x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts @@ -8,31 +8,6 @@ import { TIPage, TIPageId } from '../types'; import { threatIntelligencePages } from '../constants/navigation'; -/** - * Properties used in the Security Solution plugin to enable deep linking. - * The properties come from SecuritySolutionDeepLink (x-pack/plugins/security_solution/public/app/deep_links/index.ts). - * - * If we want to control more from within the Threat Intelligence plugin, we can keep growing this interface. - */ -interface TIDeepLink { - /** - * Optional keywords to match with in deep links search. Omit if this part of the hierarchy does not have a page URL. - */ - keywords?: string[]; - /** - * Identifier to represent this sublink, should be unique for this application. - */ - id: TId; - /** - * URL path to access this link, relative to the application's appRoute. - */ - path: string; - /** - * Title to label represent this deep link. - **/ - title: string; -} - /** * Properties used in the Security Solution plugin to add links to the navigation. * The properties come from LinkItem (x-pack/plugins/security_solution/public/common/links/types.ts). @@ -62,45 +37,6 @@ interface TILinkItem { title: string; } -/** - * Properties used in the Security Solution plugin to add links to the old navigation. - * The properties comes from NavTab (x-pack/plugins/security_solution/public/common/components/navigation/types.ts). - * - * If we want to control more from within the Threat Intelligence plugin, we can keep growing this interface. - */ -interface TINavTab { - /** - * Nav tab id. - */ - id: TId; - /** - * Name displayed in the sidenav. - */ - name: string; - /** - * Page's path to navigate to when clicked. - */ - href: string; - /** - * Disables nav tab. - */ - disabled: boolean; -} - -/** - * Gets the threat intelligence properties of a TI page for deep linking in the security solution. - * @param threatIntelligencePage the name of the threat intelligence page. - * @returns a {@link TIDeepLink} - */ -export const getSecuritySolutionDeepLink = ( - threatIntelligencePage: TIPage -): TIDeepLink => ({ - id: threatIntelligencePages[threatIntelligencePage].id as TId, - title: threatIntelligencePages[threatIntelligencePage].newNavigationName, - path: threatIntelligencePages[threatIntelligencePage].path, - keywords: threatIntelligencePages[threatIntelligencePage].keywords, -}); - /** * Gets the threat intelligence properties of a TI page for navigation in the security solution. * @param threatIntelligencePage the name of the threat intelligence page. @@ -115,19 +51,3 @@ export const getSecuritySolutionLink = ( description: threatIntelligencePages[threatIntelligencePage].description, globalSearchKeywords: threatIntelligencePages[threatIntelligencePage].globalSearchKeywords, }); - -/** - * Gets the threat intelligence properties of a TI page for navigation in the old security solution navigation. - * @param threatIntelligencePage the name of the threat intelligence page. - * @param basePath the base path for links. - * @returns a {@link TINavTab} - */ -export const getSecuritySolutionNavTab = ( - threatIntelligencePage: TIPage, - basePath: string -): TINavTab => ({ - id: threatIntelligencePages[threatIntelligencePage].id as TId, - name: threatIntelligencePages[threatIntelligencePage].oldNavigationName, - href: `${basePath}${threatIntelligencePages[threatIntelligencePage].path}`, - disabled: threatIntelligencePages[threatIntelligencePage].disabled, -}); diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index ac7d24345abfb..c21c4828cf691 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -29528,7 +29528,6 @@ "xpack.securitySolution.uiSettings.defaultThreatIndexDescription": "

Liste d'index Threat Intelligence séparés par des virgules à partir de laquelle l'application Security collecte les indicateurs.

", "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

Période de temps par défaut dans le filtre de temps Security.

", "xpack.securitySolution.uiSettings.enableCcsWarningDescription": "

Active les avertissements de vérification des privilèges dans les règles relatives aux index CCS

", - "xpack.securitySolution.uiSettings.enableGroupedNavigationDescription": "

Améliorez votre expérience avec la nouvelle navigation organisée et optimisée autour des workflows les plus importants.

", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

Active le fil d'actualités

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledDescription": "

Active l'exécution de règle étendue pour le logging dans les index .kibana-event-log-*. Affiche les événements d'exécution simples sur la page Détails de la règle.

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingMinLevelDescription": "

Définit le niveau de log minimum à partir duquel les règles écrivent des logs étendus dans les index .kibana-event-log-*. Ceci affecte uniquement les événements de type Message, les autres événements sont écrits dans .kibana-event-log-* quel que soit ce paramètre et leur niveau de log.

", @@ -33413,39 +33412,6 @@ "xpack.securitySolution.search.administration.eventFilters": "Filtres d'événements", "xpack.securitySolution.search.administration.hostIsolationExceptions": "Exceptions d'isolation de l'hôte", "xpack.securitySolution.search.administration.trustedApps": "Applications de confiance", - "xpack.securitySolution.search.alerts": "Alertes", - "xpack.securitySolution.search.dashboards": "Tableaux de bord", - "xpack.securitySolution.search.dataQualityDashboard": "Qualité des données", - "xpack.securitySolution.search.detect": "Détecter", - "xpack.securitySolution.search.detectionAndResponse": "Détection et réponse", - "xpack.securitySolution.search.entityAnalytics": "Analyse des entités", - "xpack.securitySolution.search.exceptions": "Listes d'exceptions", - "xpack.securitySolution.search.explore": "Explorer", - "xpack.securitySolution.search.getStarted": "Premiers pas", - "xpack.securitySolution.search.hosts": "Hôtes", - "xpack.securitySolution.search.hosts.anomalies": "Anomalies", - "xpack.securitySolution.search.hosts.events": "Événements", - "xpack.securitySolution.search.hosts.risk": "Risque de l'hôte", - "xpack.securitySolution.search.hosts.sessions": "Sessions", - "xpack.securitySolution.search.hosts.uncommonProcesses": "Processus inhabituels", - "xpack.securitySolution.search.investigate": "Examiner", - "xpack.securitySolution.search.kubernetes": "Kubernetes", - "xpack.securitySolution.search.manage": "Gérer", - "xpack.securitySolution.search.network": "Réseau", - "xpack.securitySolution.search.network.anomalies": "Anomalies", - "xpack.securitySolution.search.network.dns": "DNS", - "xpack.securitySolution.search.network.events": "Événements", - "xpack.securitySolution.search.network.http": "HTTP", - "xpack.securitySolution.search.network.tls": "TLS", - "xpack.securitySolution.search.overview": "Aperçu", - "xpack.securitySolution.search.rules": "Règles", - "xpack.securitySolution.search.timeline.templates": "Modèles", - "xpack.securitySolution.search.timelines": "Chronologies", - "xpack.securitySolution.search.users": "Utilisateurs", - "xpack.securitySolution.search.users.anomalies": "Anomalies", - "xpack.securitySolution.search.users.authentications": "Authentifications", - "xpack.securitySolution.search.users.events": "Événements", - "xpack.securitySolution.search.users.risk": "Risque de l'utilisateur", "xpack.securitySolution.sections.actionForm.addResponseActionButtonLabel": "Ajouter une action de réponse", "xpack.securitySolution.selector.grouping.hostName.label": "Nom d'hôte", "xpack.securitySolution.selector.grouping.sourceIP.label": "IP source", @@ -33787,7 +33753,6 @@ "xpack.securitySolution.uiSettings.defaultThreatIndexLabel": "Index de menaces", "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "Période du filtre de temps", "xpack.securitySolution.uiSettings.enableCcsReadWarningLabel": "Avertissement lié aux privilèges de la règle CCS", - "xpack.securitySolution.uiSettings.enableGroupedNavigation": "Nouvelle navigation simplifiée", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "Fil d'actualités", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledLabel": "Logging étendu de l’exécution des règles", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingMinLevelDebug": "Déboguer", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index be981b563a09e..2761c5b83e113 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -29509,7 +29509,6 @@ "xpack.securitySolution.uiSettings.defaultThreatIndexDescription": "

セキュリティアプリが指標を収集するThreat Intelligenceインデックスのカンマ区切りのリスト。

", "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

セキュリティ時間フィルダーのデフォルトの期間です。

", "xpack.securitySolution.uiSettings.enableCcsWarningDescription": "

CCSインデックスのルールで権限チェック警告を有効にします

", - "xpack.securitySolution.uiSettings.enableGroupedNavigationDescription": "

最も重要なワークフローを中心に整理され、最適化された新しいナビゲーションで、エクスペリエンスを改善します。

", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

ニュースフィードを有効にします

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledDescription": "

.kibana-event-log-*インデックスへの拡張ルール実行ログを有効にします。[ルール詳細]ページでプレーン実行イベントが表示されます。

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingMinLevelDescription": "

最小ログレベルを設定します。ルールは、このレベル以上の拡張ログを.kibana-event-log-*インデックスに書き込みます。これはメッセージタイプのイベントにのみ影響します。他のイベントは、この設定とログレベルに関係なく、.kibana-event-log-*に書き込まれます。

", @@ -33394,39 +33393,6 @@ "xpack.securitySolution.search.administration.eventFilters": "イベントフィルター", "xpack.securitySolution.search.administration.hostIsolationExceptions": "ホスト分離例外", "xpack.securitySolution.search.administration.trustedApps": "信頼できるアプリケーション", - "xpack.securitySolution.search.alerts": "アラート", - "xpack.securitySolution.search.dashboards": "ダッシュボード", - "xpack.securitySolution.search.dataQualityDashboard": "データ品質", - "xpack.securitySolution.search.detect": "検知", - "xpack.securitySolution.search.detectionAndResponse": "検出と対応", - "xpack.securitySolution.search.entityAnalytics": "エンティティ分析", - "xpack.securitySolution.search.exceptions": "例外リスト", - "xpack.securitySolution.search.explore": "探索", - "xpack.securitySolution.search.getStarted": "はじめて使う", - "xpack.securitySolution.search.hosts": "ホスト", - "xpack.securitySolution.search.hosts.anomalies": "異常", - "xpack.securitySolution.search.hosts.events": "イベント", - "xpack.securitySolution.search.hosts.risk": "ホストリスク", - "xpack.securitySolution.search.hosts.sessions": "セッション", - "xpack.securitySolution.search.hosts.uncommonProcesses": "非共通プロセス", - "xpack.securitySolution.search.investigate": "調査", - "xpack.securitySolution.search.kubernetes": "Kubernetes", - "xpack.securitySolution.search.manage": "管理", - "xpack.securitySolution.search.network": "ネットワーク", - "xpack.securitySolution.search.network.anomalies": "異常", - "xpack.securitySolution.search.network.dns": "DNS", - "xpack.securitySolution.search.network.events": "イベント", - "xpack.securitySolution.search.network.http": "HTTP", - "xpack.securitySolution.search.network.tls": "TLS", - "xpack.securitySolution.search.overview": "概要", - "xpack.securitySolution.search.rules": "ルール", - "xpack.securitySolution.search.timeline.templates": "テンプレート", - "xpack.securitySolution.search.timelines": "タイムライン", - "xpack.securitySolution.search.users": "ユーザー", - "xpack.securitySolution.search.users.anomalies": "異常", - "xpack.securitySolution.search.users.authentications": "認証", - "xpack.securitySolution.search.users.events": "イベント", - "xpack.securitySolution.search.users.risk": "ユーザーリスク", "xpack.securitySolution.sections.actionForm.addResponseActionButtonLabel": "対応アクションの追加", "xpack.securitySolution.selector.grouping.hostName.label": "ホスト名", "xpack.securitySolution.selector.grouping.sourceIP.label": "ソース IP", @@ -33768,7 +33734,6 @@ "xpack.securitySolution.uiSettings.defaultThreatIndexLabel": "脅威インデックス", "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "時間フィルターの期間", "xpack.securitySolution.uiSettings.enableCcsReadWarningLabel": "CCSルール権限警告", - "xpack.securitySolution.uiSettings.enableGroupedNavigation": "新しい合理化されたナビゲーション", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "ニュースフィード", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledLabel": "拡張ルール実行ログ", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingMinLevelDebug": "デバッグ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 94ef77904ef4e..3fe912e8ba1f7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -29505,7 +29505,6 @@ "xpack.securitySolution.uiSettings.defaultThreatIndexDescription": "

Security 应用从中收集指标的威胁情报索引的逗号分隔列表。

", "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

Security 时间筛选中的默认时段。

", "xpack.securitySolution.uiSettings.enableCcsWarningDescription": "

在规则中为 CCS 索引启用权限检查警告

", - "xpack.securitySolution.uiSettings.enableGroupedNavigationDescription": "

利用围绕最重要的工作流进行组织和优化的新导航改进您的体验。

", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

启用新闻源

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledDescription": "

对 .kibana-event-log-* 索引启用扩展规则执行日志记录。在“规则详情”页面上显示纯执行事件。

", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingMinLevelDescription": "

设置最低日志级别,规则将从该级别起将扩展日志写入到 .kibana-event-log-* 索引。这只会影响类型为“消息”的事件,其他事件将写入到 .kibana-event-log-*,而不论此设置及其日志级别如何。

", @@ -33390,39 +33389,6 @@ "xpack.securitySolution.search.administration.eventFilters": "事件筛选", "xpack.securitySolution.search.administration.hostIsolationExceptions": "主机隔离例外", "xpack.securitySolution.search.administration.trustedApps": "受信任的应用程序", - "xpack.securitySolution.search.alerts": "告警", - "xpack.securitySolution.search.dashboards": "仪表板", - "xpack.securitySolution.search.dataQualityDashboard": "数据质量", - "xpack.securitySolution.search.detect": "检测", - "xpack.securitySolution.search.detectionAndResponse": "检测和响应", - "xpack.securitySolution.search.entityAnalytics": "实体分析", - "xpack.securitySolution.search.exceptions": "例外列表", - "xpack.securitySolution.search.explore": "浏览", - "xpack.securitySolution.search.getStarted": "入门", - "xpack.securitySolution.search.hosts": "主机", - "xpack.securitySolution.search.hosts.anomalies": "异常", - "xpack.securitySolution.search.hosts.events": "事件", - "xpack.securitySolution.search.hosts.risk": "主机风险", - "xpack.securitySolution.search.hosts.sessions": "会话", - "xpack.securitySolution.search.hosts.uncommonProcesses": "不常见进程", - "xpack.securitySolution.search.investigate": "调查", - "xpack.securitySolution.search.kubernetes": "Kubernetes", - "xpack.securitySolution.search.manage": "管理", - "xpack.securitySolution.search.network": "网络", - "xpack.securitySolution.search.network.anomalies": "异常", - "xpack.securitySolution.search.network.dns": "DNS", - "xpack.securitySolution.search.network.events": "事件", - "xpack.securitySolution.search.network.http": "HTTP", - "xpack.securitySolution.search.network.tls": "TLS", - "xpack.securitySolution.search.overview": "概览", - "xpack.securitySolution.search.rules": "规则", - "xpack.securitySolution.search.timeline.templates": "模板", - "xpack.securitySolution.search.timelines": "时间线", - "xpack.securitySolution.search.users": "用户", - "xpack.securitySolution.search.users.anomalies": "异常", - "xpack.securitySolution.search.users.authentications": "身份验证", - "xpack.securitySolution.search.users.events": "事件", - "xpack.securitySolution.search.users.risk": "用户风险", "xpack.securitySolution.sections.actionForm.addResponseActionButtonLabel": "添加响应操作", "xpack.securitySolution.selector.grouping.hostName.label": "主机名", "xpack.securitySolution.selector.grouping.sourceIP.label": "源 IP", @@ -33764,7 +33730,6 @@ "xpack.securitySolution.uiSettings.defaultThreatIndexLabel": "威胁索引", "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "时间筛选时段", "xpack.securitySolution.uiSettings.enableCcsReadWarningLabel": "CCS 规则权限警告", - "xpack.securitySolution.uiSettings.enableGroupedNavigation": "新的精简导航", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "新闻源", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingEnabledLabel": "扩展规则执行日志记录", "xpack.securitySolution.uiSettings.extendedRuleExecutionLoggingMinLevelDebug": "故障排查", From 15b31c62ba8d4a115c359d9bb723147866bbd34c Mon Sep 17 00:00:00 2001 From: Alexi Doak <109488926+doakalexi@users.noreply.github.com> Date: Wed, 31 May 2023 13:26:24 -0700 Subject: [PATCH 06/31] [ResponseOps] Throwing a mustache error when validating action message for warnings (#158668) Resolves https://github.com/elastic/kibana/issues/158666 ## Summary Adds a try/catch around `mustache.parse` to catch and ignore any errors when validating the action message for warnings. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### To verify - Create a rule and add a slack connector, and open dev tools console - In the action message type `{{` - verify that an error is not thrown and that you can add the second open curly brace --- .../lib/validate_params_for_warnings.test.ts | 4 ++++ .../lib/validate_params_for_warnings.ts | 22 ++++++++++++------- 2 files changed, 18 insertions(+), 8 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 4f3d627c4fcf8..9de5749fbc2b3 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 @@ -51,4 +51,8 @@ describe('validateParamsForWarnings', () => { test('does not returns warnings when publicUrl is not set and the value is not a string', () => { expect(validateParamsForWarnings(10, undefined, actionVariables)).toBeFalsy(); }); + + test('does not throw an error when passing in invalid mustache', () => { + expect(() => validateParamsForWarnings('{{', undefined, actionVariables)).not.toThrowError(); + }); }); 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 fe7d2b0e5ffb5..d361d6f739cdc 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 @@ -31,14 +31,20 @@ export function validateParamsForWarnings( return acc; }, new Array()); - const variables = new Set( - (Mustache.parse(value) as Array<[string, string]>) - .filter(([type]) => type === 'name') - .map(([, v]) => v) - ); - const hasUrlFields = some(publicUrlFields, (publicUrlField) => variables.has(publicUrlField)); - if (hasUrlFields) { - return publicUrlWarning; + try { + const variables = new Set( + (Mustache.parse(value) as Array<[string, string]>) + .filter(([type]) => type === 'name') + .map(([, v]) => v) + ); + const hasUrlFields = some(publicUrlFields, (publicUrlField) => variables.has(publicUrlField)); + if (hasUrlFields) { + return publicUrlWarning; + } + } catch (e) { + /* + * do nothing, we don't care if the mustache is invalid + */ } } return null; From f630d906976d3e16a16f04c8f1595026a34b244e Mon Sep 17 00:00:00 2001 From: Drew Tate Date: Wed, 31 May 2023 15:41:21 -0500 Subject: [PATCH 07/31] [Lens] library annotation groups (#152623) --- .../src/capabilities_service.mock.ts | 5 +- .../tsconfig.json | 1 - .../current_mappings.json | 11 + packages/kbn-optimizer/limits.yml | 2 +- .../group2/check_registered_types.test.ts | 1 + .../group3/dot_kibana_split.test.ts | 1 + .../group3/type_registrations.test.ts | 1 + .../expression_xy/public/plugin.ts | 4 +- .../__snapshots__/save_modal.test.js.snap | 23 +- .../embeddable/api/overlays/save_modal.tsx | 33 +- .../event_annotation/common/constants.ts | 2 + src/plugins/event_annotation/common/index.ts | 3 + src/plugins/event_annotation/common/types.ts | 17 +- src/plugins/event_annotation/kibana.jsonc | 7 +- ...t_annotation_group_saved_object_finder.tsx | 133 +++ .../__snapshots__/service.test.ts.snap | 13 + .../public/event_annotation_service/index.tsx | 16 +- .../event_annotation_service/service.test.ts | 326 +++++- .../event_annotation_service/service.tsx | 317 ++++-- .../public/event_annotation_service/types.ts | 21 +- src/plugins/event_annotation/public/mocks.ts | 7 +- src/plugins/event_annotation/public/plugin.ts | 12 +- src/plugins/event_annotation/server/plugin.ts | 6 +- .../event_annotation/server/saved_objects.ts | 50 + src/plugins/event_annotation/tsconfig.json | 4 + .../saved_object_save_modal.test.tsx.snap | 124 ++- .../save_modal/saved_object_save_modal.scss | 4 +- .../save_modal/saved_object_save_modal.tsx | 84 +- .../saved_objects_tagging_oss/public/api.ts | 5 + .../utils/get_top_nav_config.tsx | 1 + .../functional/page_objects/visualize_page.ts | 13 +- x-pack/plugins/lens/public/app_plugin/app.tsx | 25 +- .../app_plugin/lens_document_equality.test.ts | 177 +++- .../app_plugin/lens_document_equality.ts | 24 +- .../lens/public/app_plugin/mounter.tsx | 3 + .../public/app_plugin/show_underlying_data.ts | 5 +- ...ed_object_save_modal_dashboard_wrapper.tsx | 1 + .../plugins/lens/public/app_plugin/types.ts | 2 + .../lens/public/data_views_service/service.ts | 24 +- .../editor_frame/config_panel/add_layer.tsx | 158 --- .../buttons/drop_targets_utils.tsx | 4 +- .../config_panel/config_panel.test.tsx | 60 +- .../config_panel/config_panel.tsx | 57 +- .../config_panel/dimension_container.tsx | 2 +- .../layer_actions/clone_layer_action.tsx | 3 +- .../layer_actions/layer_actions.tsx | 59 +- .../layer_actions/open_layer_settings.tsx | 3 +- .../layer_actions/order_bounds.ts | 9 + .../layer_actions/remove_layer_action.tsx | 4 +- .../editor_frame/config_panel/layer_panel.tsx | 30 +- .../editor_frame/config_panel/types.ts | 6 +- .../editor_frame/data_panel_wrapper.test.tsx | 7 +- .../editor_frame/data_panel_wrapper.tsx | 9 +- .../editor_frame/editor_frame.test.tsx | 2 + .../editor_frame/editor_frame.tsx | 1 + .../editor_frame/state_helpers.ts | 86 +- .../editor_frame/suggestion_helpers.ts | 3 +- .../workspace_panel/chart_switch.test.tsx | 2 +- .../public/editor_frame_service/service.tsx | 3 + .../public/embeddable/embeddable.test.tsx | 6 + .../lens/public/embeddable/embeddable.tsx | 40 +- .../public/embeddable/embeddable_factory.ts | 10 +- .../public/mocks/data_views_service_mock.ts | 3 - .../lens/public/mocks/services_mock.tsx | 2 + .../lens/public/mocks/visualization_mock.ts | 2 +- x-pack/plugins/lens/public/plugin.ts | 32 +- .../flyout_container.scss | 2 +- .../flyout_container.tsx | 39 +- .../shared_components/static_header.tsx | 28 +- .../__snapshots__/load_initial.test.tsx.snap | 1 + .../lens/public/state_management/index.ts | 2 + .../init_middleware/load_initial.ts | 158 +-- .../state_management/lens_slice.test.ts | 2 + .../public/state_management/lens_slice.ts | 53 +- .../lens/public/state_management/types.ts | 2 + x-pack/plugins/lens/public/types.ts | 109 +- x-pack/plugins/lens/public/utils.ts | 1 + .../metric/visualization.test.ts | 2 - .../visualizations/metric/visualization.tsx | 2 - .../__snapshots__/visualization.test.tsx.snap | 133 +++ .../public/visualizations/xy/add_layer.tsx | 172 +++ .../visualizations/xy/annotations/actions.ts | 22 - .../revert_changes_action.test.tsx.snap | 44 + .../__snapshots__/save_action.test.tsx.snap | 215 ++++ .../xy/annotations/actions/index.ts | 72 ++ .../actions/revert_changes_action.test.tsx | 95 ++ .../actions/revert_changes_action.tsx | 174 ++++ .../annotations/actions/save_action.test.tsx | 324 ++++++ .../xy/annotations/actions/save_action.tsx | 281 +++++ .../annotations/actions/unlink_action.test.ts | 72 ++ .../xy/annotations/actions/unlink_action.tsx | 63 ++ .../lens/public/visualizations/xy/index.ts | 9 +- .../xy/load_annotation_library_flyout.tsx | 90 ++ .../public/visualizations/xy/state_helpers.ts | 213 +++- .../public/visualizations/xy/to_expression.ts | 11 +- .../lens/public/visualizations/xy/types.ts | 64 +- ...ization.test.ts => visualization.test.tsx} | 983 ++++++++++++++++-- .../visualizations/xy/visualization.tsx | 93 +- .../xy/visualization_helpers.tsx | 80 +- .../annotations_config_panel/index.test.tsx | 6 +- .../xy/xy_config_panel/layer_header.test.tsx | 76 ++ .../xy/xy_config_panel/layer_header.tsx | 50 +- x-pack/plugins/lens/tsconfig.json | 4 + .../public/routes/map_page/top_nav_config.tsx | 1 + .../public/components/base/tag_selector.tsx | 2 + .../saved_object_save_modal_tag_selector.tsx | 13 +- .../translations/translations/fr-FR.json | 3 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - .../apps/lens/group6/annotations.ts | 104 +- .../test/functional/page_objects/lens_page.ts | 26 +- 111 files changed, 5097 insertions(+), 916 deletions(-) create mode 100644 src/plugins/event_annotation/public/components/event_annotation_group_saved_object_finder.tsx create mode 100644 src/plugins/event_annotation/public/event_annotation_service/__snapshots__/service.test.ts.snap create mode 100644 src/plugins/event_annotation/server/saved_objects.ts delete mode 100644 x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx create mode 100644 x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_actions/order_bounds.ts rename x-pack/plugins/lens/public/{editor_frame_service/editor_frame/config_panel => shared_components}/flyout_container.scss (97%) rename x-pack/plugins/lens/public/{editor_frame_service/editor_frame/config_panel => shared_components}/flyout_container.tsx (83%) create mode 100644 x-pack/plugins/lens/public/visualizations/xy/__snapshots__/visualization.test.tsx.snap create mode 100644 x-pack/plugins/lens/public/visualizations/xy/add_layer.tsx delete mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions.ts create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/__snapshots__/revert_changes_action.test.tsx.snap create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/__snapshots__/save_action.test.tsx.snap create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/index.ts create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/revert_changes_action.test.tsx create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/revert_changes_action.tsx create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.test.tsx create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/unlink_action.test.ts create mode 100644 x-pack/plugins/lens/public/visualizations/xy/annotations/actions/unlink_action.tsx create mode 100644 x-pack/plugins/lens/public/visualizations/xy/load_annotation_library_flyout.tsx rename x-pack/plugins/lens/public/visualizations/xy/{visualization.test.ts => visualization.test.tsx} (78%) create mode 100644 x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.test.tsx diff --git a/packages/core/capabilities/core-capabilities-browser-mocks/src/capabilities_service.mock.ts b/packages/core/capabilities/core-capabilities-browser-mocks/src/capabilities_service.mock.ts index fa1636b57dedb..0f2d12390a6ae 100644 --- a/packages/core/capabilities/core-capabilities-browser-mocks/src/capabilities_service.mock.ts +++ b/packages/core/capabilities/core-capabilities-browser-mocks/src/capabilities_service.mock.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { deepFreeze } from '@kbn/std'; import type { PublicMethodsOf } from '@kbn/utility-types'; import type { CapabilitiesStart, @@ -14,11 +13,11 @@ import type { } from '@kbn/core-capabilities-browser-internal'; const createStartContractMock = (): jest.Mocked => ({ - capabilities: deepFreeze({ + capabilities: { catalogue: {}, management: {}, navLinks: {}, - }), + }, }); const createMock = (): jest.Mocked> => ({ diff --git a/packages/core/capabilities/core-capabilities-browser-mocks/tsconfig.json b/packages/core/capabilities/core-capabilities-browser-mocks/tsconfig.json index 3ef89ddcbb465..531350d618920 100644 --- a/packages/core/capabilities/core-capabilities-browser-mocks/tsconfig.json +++ b/packages/core/capabilities/core-capabilities-browser-mocks/tsconfig.json @@ -12,7 +12,6 @@ "**/*.tsx", ], "kbn_references": [ - "@kbn/std", "@kbn/utility-types", "@kbn/core-capabilities-browser-internal" ], diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index 60a3e7bcd2646..8196478232792 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -931,6 +931,17 @@ } } }, + "event-annotation-group": { + "dynamic": false, + "properties": { + "title": { + "type": "text" + }, + "description": { + "type": "text" + } + } + }, "visualization": { "dynamic": false, "properties": { diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 422130eca5608..cad710f8b64ee 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -39,7 +39,7 @@ pageLoadAssetSize: embeddableEnhanced: 22107 enterpriseSearch: 35741 esUiShared: 326654 - eventAnnotation: 20500 + eventAnnotation: 22000 exploratoryView: 74673 expressionError: 22127 expressionGauge: 25000 diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts index cc2ef92e5d6d5..8534c6da57a98 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts @@ -86,6 +86,7 @@ describe('checking migration metadata changes on all registered SO types', () => "enterprise_search_telemetry": "9ac912e1417fc8681e0cd383775382117c9e3d3d", "epm-packages": "2449bb565f987eff70b1b39578bb17e90c404c6e", "epm-packages-assets": "7a3e58efd9a14191d0d1a00b8aaed30a145fd0b1", + "event-annotation-group": "715ba867d8c68f3c9438052210ea1c30a9362582", "event_loop_delays_daily": "01b967e8e043801357503de09199dfa3853bab88", "exception-list": "4aebc4e61fb5d608cae48eaeb0977e8db21c61a4", "exception-list-agnostic": "6d3262d58eee28ac381ec9654f93126a58be6f5d", 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 a5a10cd05e574..3eaca3a8e553c 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 @@ -201,6 +201,7 @@ describe('split .kibana index into multiple system indices', () => { "enterprise_search_telemetry", "epm-packages", "epm-packages-assets", + "event-annotation-group", "event_loop_delays_daily", "exception-list", "exception-list-agnostic", diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts index f528d6af100e3..ed6cd97136781 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts @@ -43,6 +43,7 @@ const previouslyRegisteredTypes = [ 'csp-rule-template', 'csp_rule', 'dashboard', + 'event-annotation-group', 'endpoint:user-artifact', 'endpoint:user-artifact-manifest', 'enterprise_search_telemetry', diff --git a/src/plugins/chart_expressions/expression_xy/public/plugin.ts b/src/plugins/chart_expressions/expression_xy/public/plugin.ts index 9c76a0d59395f..c818377896421 100755 --- a/src/plugins/chart_expressions/expression_xy/public/plugin.ts +++ b/src/plugins/chart_expressions/expression_xy/public/plugin.ts @@ -12,7 +12,7 @@ import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { ChartsPluginStart } from '@kbn/charts-plugin/public'; import { CoreSetup, CoreStart, IUiSettingsClient } from '@kbn/core/public'; -import { EventAnnotationPluginSetup } from '@kbn/event-annotation-plugin/public'; +import type { EventAnnotationPluginStart } from '@kbn/event-annotation-plugin/public'; import { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; import { ExpressionXyPluginSetup, ExpressionXyPluginStart, SetupDeps } from './types'; import { @@ -37,7 +37,7 @@ export interface XYPluginStartDependencies { data: DataPublicPluginStart; fieldFormats: FieldFormatsStart; charts: ChartsPluginStart; - eventAnnotation: EventAnnotationPluginSetup; + eventAnnotation: EventAnnotationPluginStart; usageCollection?: UsageCollectionStart; } diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/save_modal.test.js.snap b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/save_modal.test.js.snap index dbf3cb7ab8241..05a8cc2964003 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/save_modal.test.js.snap +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/__snapshots__/save_modal.test.js.snap @@ -2,32 +2,13 @@ exports[`renders DashboardSaveModal 1`] = ` - - } - labelType="label" - > - - } showCopyOnSave={true} - showDescription={false} + showDescription={true} title="dash title" /> `; diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx index 2f2254e054c21..737b8eac640f4 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiFormRow, EuiTextArea, EuiSwitch } from '@elastic/eui'; +import { EuiFormRow, EuiSwitch } from '@elastic/eui'; import { SavedObjectSaveModal } from '@kbn/saved-objects-plugin/public'; import type { DashboardSaveOptions } from '../../../types'; @@ -39,14 +39,12 @@ interface Props { } interface State { - description: string; tags: string[]; timeRestore: boolean; } export class DashboardSaveModal extends React.Component { state: State = { - description: this.props.description, timeRestore: this.props.timeRestore, tags: this.props.tags ?? [], }; @@ -57,18 +55,20 @@ export class DashboardSaveModal extends React.Component { saveDashboard = ({ newTitle, + newDescription, newCopyOnSave, isTitleDuplicateConfirmed, onTitleDuplicate, }: { newTitle: string; + newDescription: string; newCopyOnSave: boolean; isTitleDuplicateConfirmed: boolean; onTitleDuplicate: () => void; }) => { this.props.onSave({ newTitle, - newDescription: this.state.description, + newDescription, newCopyOnSave, newTimeRestore: this.state.timeRestore, isTitleDuplicateConfirmed, @@ -77,12 +77,6 @@ export class DashboardSaveModal extends React.Component { }); }; - onDescriptionChange = (event: any) => { - this.setState({ - description: event.target.value, - }); - }; - onTimeRestoreChange = (event: any) => { this.setState({ timeRestore: event.target.checked, @@ -102,26 +96,12 @@ export class DashboardSaveModal extends React.Component { tags, }); }} + markOptional /> ) : undefined; return ( - - } - > - - - {tagSelector} { onSave={this.saveDashboard} onClose={this.props.onClose} title={this.props.title} + description={this.props.description} + showDescription showCopyOnSave={this.props.showCopyOnSave} initialCopyOnSave={this.props.showCopyOnSave} objectType={i18n.translate('dashboard.topNav.saveModal.objectType', { defaultMessage: 'dashboard', })} options={this.renderDashboardSaveOptions()} - showDescription={false} /> ); } diff --git a/src/plugins/event_annotation/common/constants.ts b/src/plugins/event_annotation/common/constants.ts index 3f3f9877b9786..04255cee00c22 100644 --- a/src/plugins/event_annotation/common/constants.ts +++ b/src/plugins/event_annotation/common/constants.ts @@ -23,3 +23,5 @@ export const AvailableAnnotationIcons = { TAG: 'tag', TRIANGLE: 'triangle', } as const; + +export const EVENT_ANNOTATION_GROUP_TYPE = 'event-annotation-group'; diff --git a/src/plugins/event_annotation/common/index.ts b/src/plugins/event_annotation/common/index.ts index 779d0e13e7813..f7a62d4f3918a 100644 --- a/src/plugins/event_annotation/common/index.ts +++ b/src/plugins/event_annotation/common/index.ts @@ -33,4 +33,7 @@ export type { QueryPointEventAnnotationConfig, AvailableAnnotationIcon, EventAnnotationOutput, + EventAnnotationGroupAttributes, } from './types'; + +export { EVENT_ANNOTATION_GROUP_TYPE } from './constants'; diff --git a/src/plugins/event_annotation/common/types.ts b/src/plugins/event_annotation/common/types.ts index 5f869cbee5520..b3e704ef647e5 100644 --- a/src/plugins/event_annotation/common/types.ts +++ b/src/plugins/event_annotation/common/types.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { KibanaQueryOutput } from '@kbn/data-plugin/common'; +import { DataViewSpec, KibanaQueryOutput } from '@kbn/data-plugin/common'; import { DatatableColumn } from '@kbn/expressions-plugin/common'; import { $Values } from '@kbn/utility-types'; import { AvailableAnnotationIcons } from './constants'; @@ -82,10 +82,23 @@ export type EventAnnotationConfig = | RangeEventAnnotationConfig | QueryPointEventAnnotationConfig; +export interface EventAnnotationGroupAttributes { + title: string; + description: string; + tags: string[]; + ignoreGlobalFilters: boolean; + annotations: EventAnnotationConfig[]; + dataViewSpec?: DataViewSpec; +} + export interface EventAnnotationGroupConfig { annotations: EventAnnotationConfig[]; indexPatternId: string; - ignoreGlobalFilters?: boolean; + ignoreGlobalFilters: boolean; + title: string; + description: string; + tags: string[]; + dataViewSpec?: DataViewSpec; } export type EventAnnotationArgs = diff --git a/src/plugins/event_annotation/kibana.jsonc b/src/plugins/event_annotation/kibana.jsonc index f4f2a4791cfbb..b4df5edf135af 100644 --- a/src/plugins/event_annotation/kibana.jsonc +++ b/src/plugins/event_annotation/kibana.jsonc @@ -9,7 +9,12 @@ "browser": true, "requiredPlugins": [ "expressions", - "data" + "savedObjectsManagement", + "data", + ], + "requiredBundles": [ + "savedObjectsFinder", + "dataViews" ], "extraPublicDirs": [ "common" 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 new file mode 100644 index 0000000000000..34b1ce7eb0694 --- /dev/null +++ b/src/plugins/event_annotation/public/components/event_annotation_group_saved_object_finder.tsx @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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, { useEffect, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { CoreStart } from '@kbn/core/public'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; +import type { SavedObjectCommon } from '@kbn/saved-objects-finder-plugin/common'; +import { SavedObjectFinder } from '@kbn/saved-objects-finder-plugin/public'; +import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; +import { + EuiButton, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiText, +} from '@elastic/eui'; +import { css } from '@emotion/react'; +import { EVENT_ANNOTATION_GROUP_TYPE } from '../../common'; + +export const EventAnnotationGroupSavedObjectFinder = ({ + uiSettings, + http, + savedObjectsManagement, + fixedPageSize = 10, + checkHasAnnotationGroups, + onChoose, + onCreateNew, +}: { + uiSettings: IUiSettingsClient; + http: CoreStart['http']; + savedObjectsManagement: SavedObjectsManagementPluginStart; + fixedPageSize?: number; + checkHasAnnotationGroups: () => Promise; + onChoose: (value: { + id: string; + type: string; + fullName: string; + savedObject: SavedObjectCommon; + }) => void; + onCreateNew: () => void; +}) => { + const [hasAnnotationGroups, setHasAnnotationGroups] = useState(); + + useEffect(() => { + checkHasAnnotationGroups().then(setHasAnnotationGroups); + }, [checkHasAnnotationGroups]); + + return hasAnnotationGroups === undefined ? ( + + + + + + ) : hasAnnotationGroups === false ? ( + + + + + } + body={ + +

+ +

+
+ } + actions={ + onCreateNew()} size="s"> + + + } + /> +
+ ) : ( + { + onChoose({ id, type, fullName, savedObject }); + }} + showFilter={false} + noItemsMessage={ + + } + savedObjectMetaData={savedObjectMetaData} + services={{ + uiSettings, + http, + savedObjectsManagement, + }} + /> + ); +}; + +const savedObjectMetaData = [ + { + type: EVENT_ANNOTATION_GROUP_TYPE, + getIconForSavedObject: () => 'annotation', + name: i18n.translate('eventAnnotation.eventAnnotationGroup.metadata.name', { + defaultMessage: 'Annotations Groups', + }), + includeFields: ['*'], + }, +]; diff --git a/src/plugins/event_annotation/public/event_annotation_service/__snapshots__/service.test.ts.snap b/src/plugins/event_annotation/public/event_annotation_service/__snapshots__/service.test.ts.snap new file mode 100644 index 0000000000000..73073c0e7ea16 --- /dev/null +++ b/src/plugins/event_annotation/public/event_annotation_service/__snapshots__/service.test.ts.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Event Annotation Service loadAnnotationGroup should properly load an annotation group with a multiple annotation 1`] = ` +Object { + "annotations": undefined, + "dataViewSpec": undefined, + "description": undefined, + "ignoreGlobalFilters": undefined, + "indexPatternId": "ipid", + "tags": undefined, + "title": "groupTitle", +} +`; diff --git a/src/plugins/event_annotation/public/event_annotation_service/index.tsx b/src/plugins/event_annotation/public/event_annotation_service/index.tsx index e967a7cb0f0a2..18ef89681d621 100644 --- a/src/plugins/event_annotation/public/event_annotation_service/index.tsx +++ b/src/plugins/event_annotation/public/event_annotation_service/index.tsx @@ -6,14 +6,28 @@ * Side Public License, v 1. */ +import { CoreStart } from '@kbn/core/public'; +import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; import { EventAnnotationServiceType } from './types'; export class EventAnnotationService { private eventAnnotationService?: EventAnnotationServiceType; + + private core: CoreStart; + private savedObjectsManagement: SavedObjectsManagementPluginStart; + + constructor(core: CoreStart, savedObjectsManagement: SavedObjectsManagementPluginStart) { + this.core = core; + this.savedObjectsManagement = savedObjectsManagement; + } + public async getService() { if (!this.eventAnnotationService) { const { getEventAnnotationService } = await import('./service'); - this.eventAnnotationService = getEventAnnotationService(); + this.eventAnnotationService = getEventAnnotationService( + this.core, + this.savedObjectsManagement + ); } return this.eventAnnotationService; } diff --git a/src/plugins/event_annotation/public/event_annotation_service/service.test.ts b/src/plugins/event_annotation/public/event_annotation_service/service.test.ts index 5df25bc69d308..c131ca288a88d 100644 --- a/src/plugins/event_annotation/public/event_annotation_service/service.test.ts +++ b/src/plugins/event_annotation/public/event_annotation_service/service.test.ts @@ -6,14 +6,150 @@ * Side Public License, v 1. */ +import { CoreStart, SimpleSavedObject } from '@kbn/core/public'; +import { coreMock } from '@kbn/core/public/mocks'; +import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; +import { EventAnnotationConfig, EventAnnotationGroupAttributes } from '../../common'; import { getEventAnnotationService } from './service'; import { EventAnnotationServiceType } from './types'; +type AnnotationGroupSavedObject = SimpleSavedObject; + +const annotationGroupResolveMocks: Record = { + nonExistingGroup: { + attributes: {} as EventAnnotationGroupAttributes, + references: [], + id: 'nonExistingGroup', + error: { + error: 'Saved object not found', + statusCode: 404, + message: 'Not found', + }, + } as Partial as AnnotationGroupSavedObject, + noAnnotations: { + attributes: { + title: 'groupTitle', + description: '', + tags: [], + ignoreGlobalFilters: false, + annotations: [], + }, + type: 'event-annotation-group', + references: [ + { + id: 'ipid', + name: 'ipid', + type: 'index-pattern', + }, + ], + } as Partial as AnnotationGroupSavedObject, + multiAnnotations: { + attributes: { + title: 'groupTitle', + }, + id: 'multiAnnotations', + type: 'event-annotation-group', + references: [ + { + id: 'ipid', + name: 'ipid', + type: 'index-pattern', + }, + ], + } as Partial as AnnotationGroupSavedObject, + withAdHocDataView: { + attributes: { + title: 'groupTitle', + dataViewSpec: { + id: 'my-id', + }, + } as Partial, + id: 'multiAnnotations', + type: 'event-annotation-group', + references: [], + } as Partial as AnnotationGroupSavedObject, +}; + +const annotationResolveMocks = { + nonExistingGroup: { savedObjects: [] }, + noAnnotations: { savedObjects: [] }, + multiAnnotations: { + savedObjects: [ + { + id: 'annotation1', + attributes: { + id: 'annotation1', + type: 'manual', + key: { type: 'point_in_time' as const, timestamp: '2022-03-18T08:25:00.000Z' }, + label: 'Event', + icon: 'triangle' as const, + color: 'red', + lineStyle: 'dashed' as const, + lineWidth: 3, + } as EventAnnotationConfig, + type: 'event-annotation', + references: [ + { + id: 'multiAnnotations', + name: 'event_annotation_group_ref', + type: 'event-annotation-group', + }, + ], + }, + { + id: 'annotation2', + attributes: { + id: 'ann2', + label: 'Query based event', + icon: 'triangle', + color: 'red', + type: 'query', + timeField: 'timestamp', + key: { + type: 'point_in_time', + }, + lineStyle: 'dashed', + lineWidth: 3, + filter: { type: 'kibana_query', query: '', language: 'kuery' }, + } as EventAnnotationConfig, + type: 'event-annotation', + references: [ + { + id: 'multiAnnotations', + name: 'event_annotation_group_ref', + type: 'event-annotation-group', + }, + ], + }, + ], + }, +}; + +let core: CoreStart; + describe('Event Annotation Service', () => { let eventAnnotationService: EventAnnotationServiceType; - beforeAll(() => { - eventAnnotationService = getEventAnnotationService(); + beforeEach(() => { + core = coreMock.createStart(); + (core.savedObjects.client.create as jest.Mock).mockImplementation(() => { + return annotationGroupResolveMocks.multiAnnotations; + }); + (core.savedObjects.client.get as jest.Mock).mockImplementation((_type, id) => { + const typedId = id as keyof typeof annotationGroupResolveMocks; + return annotationGroupResolveMocks[typedId]; + }); + (core.savedObjects.client.bulkCreate as jest.Mock).mockImplementation(() => { + return annotationResolveMocks.multiAnnotations; + }); + eventAnnotationService = getEventAnnotationService( + core, + {} as SavedObjectsManagementPluginStart + ); }); + afterEach(() => { + jest.clearAllMocks(); + }); + describe('toExpression', () => { it('should work for an empty list', () => { expect(eventAnnotationService.toExpression([])).toEqual([]); @@ -318,4 +454,190 @@ describe('Event Annotation Service', () => { } ); }); + describe('loadAnnotationGroup', () => { + it('should throw error when loading group doesnt exist', async () => { + expect(() => eventAnnotationService.loadAnnotationGroup('nonExistingGroup')).rejects + .toMatchInlineSnapshot(` + Object { + "error": "Saved object not found", + "message": "Not found", + "statusCode": 404, + } + `); + }); + it('should properly load an annotation group with no annotation', async () => { + expect(await eventAnnotationService.loadAnnotationGroup('noAnnotations')) + .toMatchInlineSnapshot(` + Object { + "annotations": Array [], + "dataViewSpec": undefined, + "description": "", + "ignoreGlobalFilters": false, + "indexPatternId": "ipid", + "tags": Array [], + "title": "groupTitle", + } + `); + }); + it('should properly load an annotation group with a multiple annotation', async () => { + expect( + await eventAnnotationService.loadAnnotationGroup('multiAnnotations') + ).toMatchSnapshot(); + }); + it('populates id if group has ad-hoc data view', async () => { + const group = await eventAnnotationService.loadAnnotationGroup('withAdHocDataView'); + + expect(group.indexPatternId).toBe(group.dataViewSpec?.id); + }); + }); + // describe.skip('deleteAnnotationGroup', () => { + // it('deletes annotation group along with annotations that reference them', async () => { + // await eventAnnotationService.deleteAnnotationGroup('multiAnnotations'); + // expect(core.savedObjects.client.bulkDelete).toHaveBeenCalledWith([ + // { id: 'multiAnnotations', type: 'event-annotation-group' }, + // { id: 'annotation1', type: 'event-annotation' }, + // { id: 'annotation2', type: 'event-annotation' }, + // ]); + // }); + // }); + describe('createAnnotationGroup', () => { + it('creates annotation group along with annotations', async () => { + const annotations = [ + annotationResolveMocks.multiAnnotations.savedObjects[0].attributes, + annotationResolveMocks.multiAnnotations.savedObjects[1].attributes, + ]; + await eventAnnotationService.createAnnotationGroup({ + title: 'newGroupTitle', + description: 'my description', + tags: ['my', 'many', 'tags'], + indexPatternId: 'ipid', + ignoreGlobalFilters: false, + annotations, + }); + expect(core.savedObjects.client.create).toHaveBeenCalledWith( + 'event-annotation-group', + { + title: 'newGroupTitle', + description: 'my description', + tags: ['my', 'many', 'tags'], + ignoreGlobalFilters: false, + dataViewSpec: null, + annotations, + }, + { + references: [ + { + id: 'ipid', + name: 'event-annotation-group_dataView-ref-ipid', + type: 'index-pattern', + }, + ], + } + ); + }); + }); + describe('updateAnnotationGroup', () => { + it('updates annotation group attributes', async () => { + await eventAnnotationService.updateAnnotationGroup( + { + title: 'newTitle', + description: '', + tags: [], + indexPatternId: 'newId', + annotations: [], + ignoreGlobalFilters: false, + }, + 'multiAnnotations' + ); + expect(core.savedObjects.client.update).toHaveBeenCalledWith( + 'event-annotation-group', + 'multiAnnotations', + { + title: 'newTitle', + description: '', + tags: [], + annotations: [], + dataViewSpec: null, + ignoreGlobalFilters: false, + }, + { + references: [ + { + id: 'newId', + name: 'event-annotation-group_dataView-ref-newId', + type: 'index-pattern', + }, + ], + } + ); + }); + }); + // describe.skip('updateAnnotations', () => { + // const upsert = [ + // { + // id: 'annotation2', + // label: 'Query based event', + // icon: 'triangle', + // color: 'red', + // type: 'query', + // timeField: 'timestamp', + // key: { + // type: 'point_in_time', + // }, + // lineStyle: 'dashed', + // lineWidth: 3, + // filter: { type: 'kibana_query', query: '', language: 'kuery' }, + // }, + // { + // id: 'annotation4', + // label: 'Query based event', + // type: 'query', + // timeField: 'timestamp', + // key: { + // type: 'point_in_time', + // }, + // filter: { type: 'kibana_query', query: '', language: 'kuery' }, + // }, + // ] as EventAnnotationConfig[]; + // it('updates annotations - deletes annotations', async () => { + // await eventAnnotationService.updateAnnotations('multiAnnotations', { + // delete: ['annotation1', 'annotation2'], + // }); + // expect(core.savedObjects.client.bulkDelete).toHaveBeenCalledWith([ + // { id: 'annotation1', type: 'event-annotation' }, + // { id: 'annotation2', type: 'event-annotation' }, + // ]); + // }); + // it('updates annotations - inserts new annotations', async () => { + // await eventAnnotationService.updateAnnotations('multiAnnotations', { upsert }); + // expect(core.savedObjects.client.bulkCreate).toHaveBeenCalledWith([ + // { + // id: 'annotation2', + // type: 'event-annotation', + // attributes: upsert[0], + // overwrite: true, + // references: [ + // { + // id: 'multiAnnotations', + // name: 'event-annotation-group-ref-annotation2', + // type: 'event-annotation-group', + // }, + // ], + // }, + // { + // id: 'annotation4', + // type: 'event-annotation', + // attributes: upsert[1], + // overwrite: true, + // references: [ + // { + // id: 'multiAnnotations', + // name: 'event-annotation-group-ref-annotation4', + // type: 'event-annotation-group', + // }, + // ], + // }, + // ]); + // }); + // }); }); diff --git a/src/plugins/event_annotation/public/event_annotation_service/service.tsx b/src/plugins/event_annotation/public/event_annotation_service/service.tsx index 1b2bdbc9611cc..a5ac2e265b0f7 100644 --- a/src/plugins/event_annotation/public/event_annotation_service/service.tsx +++ b/src/plugins/event_annotation/public/event_annotation_service/service.tsx @@ -6,10 +6,19 @@ * Side Public License, v 1. */ +import React from 'react'; import { partition } from 'lodash'; import { queryToAst } from '@kbn/data-plugin/common'; import { ExpressionAstExpression } from '@kbn/expressions-plugin/common'; -import { EventAnnotationConfig } from '../../common'; +import { CoreStart, SavedObjectReference, SavedObjectsClientContract } from '@kbn/core/public'; +import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; +import { DataViewPersistableStateService } from '@kbn/data-views-plugin/common'; +import { + EventAnnotationConfig, + EventAnnotationGroupAttributes, + EventAnnotationGroupConfig, + EVENT_ANNOTATION_GROUP_TYPE, +} from '../../common'; import { EventAnnotationServiceType } from './types'; import { defaultAnnotationColor, @@ -18,108 +27,138 @@ import { isRangeAnnotationConfig, isQueryAnnotationConfig, } from './helpers'; +import { EventAnnotationGroupSavedObjectFinder } from '../components/event_annotation_group_saved_object_finder'; export function hasIcon(icon: string | undefined): icon is string { return icon != null && icon !== 'empty'; } -export function getEventAnnotationService(): EventAnnotationServiceType { - const annotationsToExpression = (annotations: EventAnnotationConfig[]) => { - const [queryBasedAnnotations, manualBasedAnnotations] = partition( - annotations, - isQueryAnnotationConfig +export function getEventAnnotationService( + core: CoreStart, + savedObjectsManagement: SavedObjectsManagementPluginStart +): EventAnnotationServiceType { + const client: SavedObjectsClientContract = core.savedObjects.client; + + const loadAnnotationGroup = async ( + savedObjectId: string + ): Promise => { + const savedObject = await client.get( + EVENT_ANNOTATION_GROUP_TYPE, + savedObjectId ); - const expressions = []; - - for (const annotation of manualBasedAnnotations) { - if (isRangeAnnotationConfig(annotation)) { - const { label, color, key, outside, id } = annotation; - const { timestamp: time, endTimestamp: endTime } = key; - expressions.push({ - type: 'expression' as const, - chain: [ - { - type: 'function' as const, - function: 'manual_range_event_annotation', - arguments: { - id: [id], - time: [time], - endTime: [endTime], - label: [label || defaultAnnotationLabel], - color: [color || defaultAnnotationRangeColor], - outside: [Boolean(outside)], - isHidden: [Boolean(annotation.isHidden)], - }, - }, - ], - }); - } else { - const { label, color, lineStyle, lineWidth, icon, key, textVisibility, id } = annotation; - expressions.push({ - type: 'expression' as const, - chain: [ - { - type: 'function' as const, - function: 'manual_point_event_annotation', - arguments: { - id: [id], - time: [key.timestamp], - label: [label || defaultAnnotationLabel], - color: [color || defaultAnnotationColor], - lineWidth: [lineWidth || 1], - lineStyle: [lineStyle || 'solid'], - icon: hasIcon(icon) ? [icon] : ['triangle'], - textVisibility: [textVisibility || false], - isHidden: [Boolean(annotation.isHidden)], - }, - }, - ], - }); - } + if (savedObject.error) { + throw savedObject.error; } - for (const annotation of queryBasedAnnotations) { - const { - id, - label, - color, - lineStyle, - lineWidth, - icon, - timeField, - textVisibility, - textField, - filter, - extraFields, - } = annotation; - expressions.push({ - type: 'expression' as const, - chain: [ - { - type: 'function' as const, - function: 'query_point_event_annotation', - arguments: { - id: [id], - timeField: timeField ? [timeField] : [], - label: [label || defaultAnnotationLabel], - color: [color || defaultAnnotationColor], - lineWidth: [lineWidth || 1], - lineStyle: [lineStyle || 'solid'], - icon: hasIcon(icon) ? [icon] : ['triangle'], - textVisibility: [textVisibility || false], - textField: textVisibility && textField ? [textField] : [], - filter: filter ? [queryToAst(filter)] : [], - extraFields: extraFields || [], - isHidden: [Boolean(annotation.isHidden)], - }, - }, - ], - }); + const adHocDataViewSpec = savedObject.attributes.dataViewSpec + ? DataViewPersistableStateService.inject( + savedObject.attributes.dataViewSpec, + savedObject.references + ) + : undefined; + + return { + title: savedObject.attributes.title, + description: savedObject.attributes.description, + tags: savedObject.attributes.tags, + ignoreGlobalFilters: savedObject.attributes.ignoreGlobalFilters, + indexPatternId: adHocDataViewSpec + ? adHocDataViewSpec.id! + : savedObject.references.find((ref) => ref.type === 'index-pattern')?.id!, + annotations: savedObject.attributes.annotations, + dataViewSpec: adHocDataViewSpec, + }; + }; + + const extractDataViewInformation = (group: EventAnnotationGroupConfig) => { + let { dataViewSpec = null } = group; + + let references: SavedObjectReference[]; + + if (dataViewSpec) { + if (!dataViewSpec.id) + throw new Error( + 'tried to create annotation group with a data view spec that did not include an ID!' + ); + + const { state, references: refsFromDataView } = + DataViewPersistableStateService.extract(dataViewSpec); + dataViewSpec = state; + references = refsFromDataView; + } else { + references = [ + { + type: 'index-pattern', + id: group.indexPatternId, + name: `event-annotation-group_dataView-ref-${group.indexPatternId}`, + }, + ]; } - return expressions; + + return { references, dataViewSpec }; + }; + + const createAnnotationGroup = async ( + group: EventAnnotationGroupConfig + ): Promise<{ id: string }> => { + const { references, dataViewSpec } = extractDataViewInformation(group); + const { title, description, tags, ignoreGlobalFilters, annotations } = group; + + const groupSavedObjectId = ( + await client.create( + EVENT_ANNOTATION_GROUP_TYPE, + { title, description, tags, ignoreGlobalFilters, annotations, dataViewSpec }, + { + references, + } + ) + ).id; + + return { id: groupSavedObjectId }; + }; + + const updateAnnotationGroup = async ( + group: EventAnnotationGroupConfig, + annotationGroupId: string + ): Promise => { + const { references, dataViewSpec } = extractDataViewInformation(group); + const { title, description, tags, ignoreGlobalFilters, annotations } = group; + + await client.update( + EVENT_ANNOTATION_GROUP_TYPE, + annotationGroupId, + { title, description, tags, ignoreGlobalFilters, annotations, dataViewSpec }, + { + references, + } + ); }; + + const checkHasAnnotationGroups = async (): Promise => { + const response = await client.find({ + type: EVENT_ANNOTATION_GROUP_TYPE, + perPage: 0, + }); + + return response.total > 0; + }; + return { + loadAnnotationGroup, + updateAnnotationGroup, + createAnnotationGroup, + renderEventAnnotationGroupSavedObjectFinder: (props) => { + return ( + + ); + }, toExpression: annotationsToExpression, toFetchExpression: ({ interval, groups }) => { if (groups.length === 0) { @@ -177,3 +216,99 @@ export function getEventAnnotationService(): EventAnnotationServiceType { }, }; } + +const annotationsToExpression = (annotations: EventAnnotationConfig[]) => { + const [queryBasedAnnotations, manualBasedAnnotations] = partition( + annotations, + isQueryAnnotationConfig + ); + + const expressions = []; + + for (const annotation of manualBasedAnnotations) { + if (isRangeAnnotationConfig(annotation)) { + const { label, color, key, outside, id } = annotation; + const { timestamp: time, endTimestamp: endTime } = key; + expressions.push({ + type: 'expression' as const, + chain: [ + { + type: 'function' as const, + function: 'manual_range_event_annotation', + arguments: { + id: [id], + time: [time], + endTime: [endTime], + label: [label || defaultAnnotationLabel], + color: [color || defaultAnnotationRangeColor], + outside: [Boolean(outside)], + isHidden: [Boolean(annotation.isHidden)], + }, + }, + ], + }); + } else { + const { label, color, lineStyle, lineWidth, icon, key, textVisibility, id } = annotation; + expressions.push({ + type: 'expression' as const, + chain: [ + { + type: 'function' as const, + function: 'manual_point_event_annotation', + arguments: { + id: [id], + time: [key.timestamp], + label: [label || defaultAnnotationLabel], + color: [color || defaultAnnotationColor], + lineWidth: [lineWidth || 1], + lineStyle: [lineStyle || 'solid'], + icon: hasIcon(icon) ? [icon] : ['triangle'], + textVisibility: [textVisibility || false], + isHidden: [Boolean(annotation.isHidden)], + }, + }, + ], + }); + } + } + + for (const annotation of queryBasedAnnotations) { + const { + id, + label, + color, + lineStyle, + lineWidth, + icon, + timeField, + textVisibility, + textField, + filter, + extraFields, + } = annotation; + expressions.push({ + type: 'expression' as const, + chain: [ + { + type: 'function' as const, + function: 'query_point_event_annotation', + arguments: { + id: [id], + timeField: timeField ? [timeField] : [], + label: [label || defaultAnnotationLabel], + color: [color || defaultAnnotationColor], + lineWidth: [lineWidth || 1], + lineStyle: [lineStyle || 'solid'], + icon: hasIcon(icon) ? [icon] : ['triangle'], + textVisibility: [textVisibility || false], + textField: textVisibility && textField ? [textField] : [], + filter: filter ? [queryToAst(filter)] : [], + extraFields: extraFields || [], + isHidden: [Boolean(annotation.isHidden)], + }, + }, + ], + }); + } + return expressions; +}; 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 cf3d759b7a324..603cc20c34bc8 100644 --- a/src/plugins/event_annotation/public/event_annotation_service/types.ts +++ b/src/plugins/event_annotation/public/event_annotation_service/types.ts @@ -7,12 +7,31 @@ */ import { ExpressionAstExpression } from '@kbn/expressions-plugin/common/ast'; +import type { SavedObjectCommon } from '@kbn/saved-objects-finder-plugin/common'; import { EventAnnotationConfig, EventAnnotationGroupConfig } from '../../common'; export interface EventAnnotationServiceType { + loadAnnotationGroup: (savedObjectId: string) => Promise; + createAnnotationGroup: (group: EventAnnotationGroupConfig) => Promise<{ id: string }>; + updateAnnotationGroup: ( + group: EventAnnotationGroupConfig, + savedObjectId: string + ) => Promise; toExpression: (props: EventAnnotationConfig[]) => ExpressionAstExpression[]; toFetchExpression: (props: { interval: string; - groups: EventAnnotationGroupConfig[]; + groups: Array< + Pick + >; }) => ExpressionAstExpression[]; + renderEventAnnotationGroupSavedObjectFinder: (props: { + fixedPageSize?: number; + onChoose: (value: { + id: string; + type: string; + fullName: string; + savedObject: SavedObjectCommon; + }) => void; + onCreateNew: () => void; + }) => JSX.Element; } diff --git a/src/plugins/event_annotation/public/mocks.ts b/src/plugins/event_annotation/public/mocks.ts index e78d4e8f75de7..100b5d3f1c3e2 100644 --- a/src/plugins/event_annotation/public/mocks.ts +++ b/src/plugins/event_annotation/public/mocks.ts @@ -6,7 +6,12 @@ * Side Public License, v 1. */ +import { coreMock } from '@kbn/core/public/mocks'; +import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; import { getEventAnnotationService } from './event_annotation_service/service'; // not really mocking but avoiding async loading -export const eventAnnotationServiceMock = getEventAnnotationService(); +export const eventAnnotationServiceMock = getEventAnnotationService( + coreMock.createStart(), + {} as SavedObjectsManagementPluginStart +); diff --git a/src/plugins/event_annotation/public/plugin.ts b/src/plugins/event_annotation/public/plugin.ts index 47df586e061d7..4d390f308a474 100644 --- a/src/plugins/event_annotation/public/plugin.ts +++ b/src/plugins/event_annotation/public/plugin.ts @@ -6,8 +6,9 @@ * Side Public License, v 1. */ -import { Plugin, CoreSetup, CoreStart, IUiSettingsClient } from '@kbn/core/public'; +import { Plugin, CoreSetup, CoreStart } from '@kbn/core/public'; import { ExpressionsSetup } from '@kbn/expressions-plugin/public'; +import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { EventAnnotationService } from './event_annotation_service'; import { @@ -19,8 +20,8 @@ import { import { getFetchEventAnnotations } from './fetch_event_annotations'; export interface EventAnnotationStartDependencies { + savedObjectsManagement: SavedObjectsManagementPluginStart; data: DataPublicPluginStart; - uiSettings: IUiSettingsClient; } interface SetupDependencies { @@ -29,14 +30,12 @@ interface SetupDependencies { /** @public */ export type EventAnnotationPluginStart = EventAnnotationService; -export type EventAnnotationPluginSetup = EventAnnotationService; +export type EventAnnotationPluginSetup = void; /** @public */ export class EventAnnotationPlugin implements Plugin { - private readonly eventAnnotationService = new EventAnnotationService(); - public setup( core: CoreSetup, dependencies: SetupDependencies @@ -48,13 +47,12 @@ export class EventAnnotationPlugin dependencies.expressions.registerFunction( getFetchEventAnnotations({ getStartServices: core.getStartServices }) ); - return this.eventAnnotationService; } public start( core: CoreStart, startDependencies: EventAnnotationStartDependencies ): EventAnnotationService { - return this.eventAnnotationService; + return new EventAnnotationService(core, startDependencies.savedObjectsManagement); } } diff --git a/src/plugins/event_annotation/server/plugin.ts b/src/plugins/event_annotation/server/plugin.ts index 4d59f0e6800dd..0ae55744016e6 100644 --- a/src/plugins/event_annotation/server/plugin.ts +++ b/src/plugins/event_annotation/server/plugin.ts @@ -15,6 +15,7 @@ import { manualRangeEventAnnotation, queryPointEventAnnotation, } from '../common'; +import { setupSavedObjects } from './saved_objects'; // import { getFetchEventAnnotations } from './fetch_event_annotations'; interface SetupDependencies { @@ -33,9 +34,8 @@ export class EventAnnotationServerPlugin implements Plugin { dependencies.expressions.registerFunction(manualRangeEventAnnotation); dependencies.expressions.registerFunction(queryPointEventAnnotation); dependencies.expressions.registerFunction(eventAnnotationGroup); - // dependencies.expressions.registerFunction( - // getFetchEventAnnotations({ getStartServices: core.getStartServices }) - // ); + + setupSavedObjects(core); return {}; } diff --git a/src/plugins/event_annotation/server/saved_objects.ts b/src/plugins/event_annotation/server/saved_objects.ts new file mode 100644 index 0000000000000..768def6b27f79 --- /dev/null +++ b/src/plugins/event_annotation/server/saved_objects.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 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 { ANALYTICS_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; +import { + CoreSetup, + mergeSavedObjectMigrationMaps, + SavedObjectMigrationMap, +} from '@kbn/core/server'; + +import { DataViewPersistableStateService } from '@kbn/data-views-plugin/common'; +import { EVENT_ANNOTATION_GROUP_TYPE } from '../common/constants'; +import { EventAnnotationGroupAttributes } from '../common/types'; + +export function setupSavedObjects(coreSetup: CoreSetup) { + coreSetup.savedObjects.registerType({ + name: EVENT_ANNOTATION_GROUP_TYPE, + indexPattern: ANALYTICS_SAVED_OBJECT_INDEX, + hidden: false, + namespaceType: 'multiple', + management: { + icon: 'flag', + defaultSearchField: 'title', + importableAndExportable: true, + getTitle: (obj: { attributes: EventAnnotationGroupAttributes }) => obj.attributes.title, + }, + migrations: () => { + const dataViewMigrations = DataViewPersistableStateService.getAllMigrations(); + return mergeSavedObjectMigrationMaps(eventAnnotationGroupMigrations, dataViewMigrations); + }, + mappings: { + dynamic: false, + properties: { + title: { + type: 'text', + }, + description: { + type: 'text', + }, + }, + }, + }); +} + +const eventAnnotationGroupMigrations: SavedObjectMigrationMap = {}; diff --git a/src/plugins/event_annotation/tsconfig.json b/src/plugins/event_annotation/tsconfig.json index 0b5e98d364fed..562bf05259c44 100644 --- a/src/plugins/event_annotation/tsconfig.json +++ b/src/plugins/event_annotation/tsconfig.json @@ -19,6 +19,10 @@ "@kbn/core-ui-settings-browser", "@kbn/datemath", "@kbn/ui-theme", + "@kbn/saved-objects-finder-plugin", + "@kbn/saved-objects-management-plugin", + "@kbn/i18n-react", + "@kbn/core-saved-objects-server" ], "exclude": [ "target/**/*", 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 0f2367910cefd..70ba2d5619d03 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 @@ -62,17 +62,45 @@ exports[`SavedObjectSaveModal should render matching snapshot 1`] = ` values={Object {}} /> } + labelAppend={ + + + + } labelType="label" >
- + + } + labelAppend={ + + + + } labelType="label" >
- + + } + labelAppend={ + + + + } labelType="label" > - + + } + labelAppend={ + + + + } labelType="label" > @@ -383,7 +477,22 @@ exports[`SavedObjectSaveModal should render matching snapshot when given options - + + hasTitleDuplicate: false, isLoading: false, visualizationDescription: this.props.description ? this.props.description : '', + hasAttemptedSubmit: false, }; public render() { - const { isTitleDuplicateConfirmed, hasTitleDuplicate, title } = this.state; + const { isTitleDuplicateConfirmed, hasTitleDuplicate, title, hasAttemptedSubmit } = this.state; const duplicateWarningId = generateId(); const hasColumns = !!this.props.rightOptions; @@ -101,7 +105,10 @@ export class SavedObjectSaveModal extends React.Component data-test-subj="savedObjectTitle" value={title} onChange={this.onTitleChange} - isInvalid={(!isTitleDuplicateConfirmed && hasTitleDuplicate) || title.length === 0} + isInvalid={ + hasAttemptedSubmit && + ((!isTitleDuplicateConfirmed && hasTitleDuplicate) || title.length === 0) + } aria-describedby={this.state.hasTitleDuplicate ? duplicateWarningId : undefined} /> @@ -135,11 +142,15 @@ export class SavedObjectSaveModal extends React.Component > - + {this.props.customModalTitle ? ( + this.props.customModalTitle + ) : ( + + )} @@ -153,11 +164,15 @@ export class SavedObjectSaveModal extends React.Component
)} {formBody} - {this.renderCopyOnSave()} - + + {this.renderCopyOnSave()} return ( + +
+ } label={ } > private onFormSubmit = (event: React.FormEvent) => { event.preventDefault(); - this.saveSavedObject(); + + const { hasAttemptedSubmit, title } = this.state; + + if (!hasAttemptedSubmit) { + this.setState({ hasAttemptedSubmit: true }); + } + + const isValid = this.props.isValid !== undefined ? this.props.isValid : true; + + if (title.length !== 0 && isValid) { + this.saveSavedObject(); + } }; private renderConfirmButton = () => { - const { isLoading, title } = this.state; + const { isLoading } = this.state; let confirmLabel: string | React.ReactNode = i18n.translate( 'savedObjects.saveModal.saveButtonLabel', @@ -269,14 +301,11 @@ export class SavedObjectSaveModal extends React.Component confirmLabel = this.props.confirmButtonLabel; } - const isValid = this.props.isValid !== undefined ? this.props.isValid : true; - return ( @@ -327,21 +356,18 @@ export class SavedObjectSaveModal extends React.Component } return ( - <> - - - } - /> - + + } + /> ); }; } diff --git a/src/plugins/saved_objects_tagging_oss/public/api.ts b/src/plugins/saved_objects_tagging_oss/public/api.ts index 54afed5d6203c..50508b4f5a0c3 100644 --- a/src/plugins/saved_objects_tagging_oss/public/api.ts +++ b/src/plugins/saved_objects_tagging_oss/public/api.ts @@ -268,6 +268,11 @@ export type SavedObjectSaveModalTagSelectorComponentProps = EuiComboBoxProps< * tags selection callback */ onTagsSelected: (ids: string[]) => void; + + /** + * Add "Optional" to the label + */ + markOptional?: boolean; }; /** diff --git a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx index 250f6b40c1e52..9bc781f464084 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx +++ b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx @@ -544,6 +544,7 @@ export const getTopNavConfig = ( onTagsSelected={(newSelection) => { selectedTags = newSelection; }} + markOptional /> ); } diff --git a/test/functional/page_objects/visualize_page.ts b/test/functional/page_objects/visualize_page.ts index be870ce24e127..bcfbc8caa9ce1 100644 --- a/test/functional/page_objects/visualize_page.ts +++ b/test/functional/page_objects/visualize_page.ts @@ -16,6 +16,7 @@ interface VisualizeSaveModalArgs { redirectToOrigin?: boolean; addToDashboard?: boolean; dashboardId?: string; + description?: string; } type DashboardPickerOption = @@ -393,10 +394,20 @@ export class VisualizePageObject extends FtrService { public async setSaveModalValues( vizName: string, - { saveAsNew, redirectToOrigin, addToDashboard, dashboardId }: VisualizeSaveModalArgs = {} + { + saveAsNew, + redirectToOrigin, + addToDashboard, + dashboardId, + description, + }: VisualizeSaveModalArgs = {} ) { await this.testSubjects.setValue('savedObjectTitle', vizName); + if (description) { + await this.testSubjects.setValue('viewDescription', description); + } + const saveAsNewCheckboxExists = await this.testSubjects.exists('saveAsNewCheckbox'); if (saveAsNewCheckboxExists) { const state = saveAsNew ? 'check' : 'uncheck'; diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index b4b45209aef4e..58d422b05adb7 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -113,6 +113,7 @@ export function App({ isLoading, isSaveable, visualization, + annotationGroups, } = useLensSelector((state) => state.lens); const selectorDependencies = useMemo( @@ -180,7 +181,9 @@ export function App({ persistedDoc, lastKnownDoc, data.query.filterManager.inject.bind(data.query.filterManager), - datasourceMap + datasourceMap, + visualizationMap, + annotationGroups ) && (isSaveable || persistedDoc) ) { @@ -209,6 +212,8 @@ export function App({ application.capabilities.visualize.save, data.query.filterManager, datasourceMap, + visualizationMap, + annotationGroups, ]); const getLegacyUrlConflictCallout = useCallback(() => { @@ -374,7 +379,14 @@ export function App({ initialDocFromContext, persistedDoc, ].map((refDoc) => - isLensEqual(refDoc, lastKnownDoc, data.query.filterManager.inject, datasourceMap) + isLensEqual( + refDoc, + lastKnownDoc, + data.query.filterManager.inject, + datasourceMap, + visualizationMap, + annotationGroups + ) ); if (initialDocFromContextUnchanged || currentDocHasBeenSavedInLens) { onAppLeave((actions) => { @@ -386,6 +398,7 @@ export function App({ } } }, [ + annotationGroups, application, data.query.filterManager.inject, datasourceMap, @@ -394,6 +407,7 @@ export function App({ lastKnownDoc, onAppLeave, persistedDoc, + visualizationMap, ]); const navigateToVizEditor = useCallback(() => { @@ -422,7 +436,6 @@ export function App({ dataViews, uiActions, core: { http, notifications, uiSettings }, - data, contextDataViewSpec: (initialContext as VisualizeFieldContext | undefined)?.dataViewSpec, updateIndexPatterns: (newIndexPatternsState, options) => { dispatch(updateIndexPatterns(newIndexPatternsState)); @@ -437,7 +450,7 @@ export function App({ } }, }), - [dataViews, uiActions, http, notifications, uiSettings, data, initialContext, dispatch] + [dataViews, uiActions, http, notifications, uiSettings, initialContext, dispatch] ); const onTextBasedSavedAndExit = useCallback(async ({ onSave, onCancel }) => { @@ -597,7 +610,9 @@ export function App({ persistedDoc, lastKnownDoc, data.query.filterManager.inject.bind(data.query.filterManager), - datasourceMap + datasourceMap, + visualizationMap, + annotationGroups ) } goBackToOriginatingApp={goBackToOriginatingApp} diff --git a/x-pack/plugins/lens/public/app_plugin/lens_document_equality.test.ts b/x-pack/plugins/lens/public/app_plugin/lens_document_equality.test.ts index 8bd1e6e980bbb..babde51e39f27 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_document_equality.test.ts +++ b/x-pack/plugins/lens/public/app_plugin/lens_document_equality.test.ts @@ -8,11 +8,19 @@ import { Filter, FilterStateStore } from '@kbn/es-query'; import { isLensEqual } from './lens_document_equality'; import { Document } from '../persistence/saved_object_store'; -import { Datasource, DatasourceMap } from '../types'; +import { + AnnotationGroups, + Datasource, + DatasourceMap, + Visualization, + VisualizationMap, +} from '../types'; + +const visualizationType = 'lnsSomeVis'; const defaultDoc: Document = { title: 'some-title', - visualizationType: 'lnsXY', + visualizationType, state: { query: { query: '', @@ -53,23 +61,67 @@ describe('lens document equality', () => { ); let mockDatasourceMap: DatasourceMap; + let mockVisualizationMap: VisualizationMap; + let mockAnnotationGroups: AnnotationGroups; beforeEach(() => { mockDatasourceMap = { - indexpattern: { isEqual: jest.fn(() => true) }, - } as unknown as DatasourceMap; + indexpattern: { isEqual: jest.fn(() => true) } as Partial as Datasource, + }; + + mockVisualizationMap = { + [visualizationType]: { + isEqual: jest.fn(() => true), + } as Partial as Visualization, + }; + + mockAnnotationGroups = {}; }); it('returns true when documents are equal', () => { expect( - isLensEqual(defaultDoc, defaultDoc, mockInjectFilterReferences, mockDatasourceMap) + isLensEqual( + defaultDoc, + defaultDoc, + mockInjectFilterReferences, + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups + ) ).toBeTruthy(); }); it('handles undefined documents', () => { - expect(isLensEqual(undefined, undefined, mockInjectFilterReferences, {})).toBeTruthy(); - expect(isLensEqual(undefined, {} as Document, mockInjectFilterReferences, {})).toBeFalsy(); - expect(isLensEqual({} as Document, undefined, mockInjectFilterReferences, {})).toBeFalsy(); + expect( + isLensEqual( + undefined, + undefined, + mockInjectFilterReferences, + {}, + mockVisualizationMap, + mockAnnotationGroups + ) + ).toBeTruthy(); + expect( + isLensEqual( + undefined, + {} as Document, + mockInjectFilterReferences, + {}, + mockVisualizationMap, + mockAnnotationGroups + ) + ).toBeFalsy(); + expect( + isLensEqual( + {} as Document, + undefined, + mockInjectFilterReferences, + {}, + mockVisualizationMap, + mockAnnotationGroups + ) + ).toBeFalsy(); }); it('should compare visualization type', () => { @@ -78,7 +130,9 @@ describe('lens document equality', () => { defaultDoc, { ...defaultDoc, visualizationType: 'other-type' }, mockInjectFilterReferences, - mockDatasourceMap + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups ) ).toBeFalsy(); }); @@ -98,26 +152,9 @@ describe('lens document equality', () => { }, }, mockInjectFilterReferences, - mockDatasourceMap - ) - ).toBeFalsy(); - }); - - it('should compare the visualization state', () => { - expect( - isLensEqual( - defaultDoc, - { - ...defaultDoc, - state: { - ...defaultDoc.state, - visualization: { - some: 'other-props', - }, - }, - }, - mockInjectFilterReferences, - mockDatasourceMap + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups ) ).toBeFalsy(); }); @@ -139,7 +176,9 @@ describe('lens document equality', () => { }, }, mockInjectFilterReferences, - { ...mockDatasourceMap, foodatasource: { isEqual: () => true } as unknown as Datasource } + { ...mockDatasourceMap, foodatasource: { isEqual: () => true } as unknown as Datasource }, + mockVisualizationMap, + mockAnnotationGroups ) ).toBeFalsy(); @@ -167,7 +206,9 @@ describe('lens document equality', () => { }, }, mockInjectFilterReferences, - { ...mockDatasourceMap, foodatasource: { isEqual: () => true } as unknown as Datasource } + { ...mockDatasourceMap, foodatasource: { isEqual: () => true } as unknown as Datasource }, + mockVisualizationMap, + mockAnnotationGroups ) ).toBeTruthy(); }); @@ -176,7 +217,67 @@ describe('lens document equality', () => { // datasource's isEqual returns false (mockDatasourceMap.indexpattern.isEqual as jest.Mock).mockReturnValue(false); expect( - isLensEqual(defaultDoc, defaultDoc, mockInjectFilterReferences, mockDatasourceMap) + isLensEqual( + defaultDoc, + defaultDoc, + mockInjectFilterReferences, + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups + ) + ).toBeFalsy(); + }); + }); + + describe('comparing the visualizations', () => { + it('delegates to visualization class if visualization.isEqual available', () => { + expect( + isLensEqual( + defaultDoc, + defaultDoc, + mockInjectFilterReferences, + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups + ) + ).toBeTruthy(); + + expect(mockVisualizationMap[visualizationType].isEqual).toHaveBeenCalled(); + + (mockVisualizationMap[visualizationType].isEqual as jest.Mock).mockReturnValue(false); + + expect( + isLensEqual( + defaultDoc, + defaultDoc, + mockInjectFilterReferences, + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups + ) + ).toBeFalsy(); + }); + + it('direct comparison if no isEqual implementation', () => { + delete mockVisualizationMap[visualizationType].isEqual; + + expect( + isLensEqual( + defaultDoc, + { + ...defaultDoc, + state: { + ...defaultDoc.state, + visualization: { + some: 'other-props', + }, + }, + }, + mockInjectFilterReferences, + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups + ) ).toBeFalsy(); }); }); @@ -197,7 +298,9 @@ describe('lens document equality', () => { defaultDoc, { ...defaultDoc, state: { ...defaultDoc.state, filters: filtersWithPinned } }, mockInjectFilterReferences, - mockDatasourceMap + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups ) ).toBeTruthy(); }); @@ -221,7 +324,9 @@ describe('lens document equality', () => { }, }, mockInjectFilterReferences, - mockDatasourceMap + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups ) ).toBeTruthy(); }); @@ -241,7 +346,9 @@ describe('lens document equality', () => { }, }, mockInjectFilterReferences, - mockDatasourceMap + mockDatasourceMap, + mockVisualizationMap, + mockAnnotationGroups ) ).toBeTruthy(); }); diff --git a/x-pack/plugins/lens/public/app_plugin/lens_document_equality.ts b/x-pack/plugins/lens/public/app_plugin/lens_document_equality.ts index dae571acf10ed..60316802ca5ea 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_document_equality.ts +++ b/x-pack/plugins/lens/public/app_plugin/lens_document_equality.ts @@ -8,7 +8,7 @@ import { isEqual, intersection, union } from 'lodash'; import { FilterManager } from '@kbn/data-plugin/public'; import { Document } from '../persistence/saved_object_store'; -import { DatasourceMap } from '../types'; +import { AnnotationGroups, DatasourceMap, VisualizationMap } from '../types'; import { removePinnedFilters } from './save_modal_container'; const removeNonSerializable = (obj: Parameters[0]) => @@ -18,7 +18,9 @@ export const isLensEqual = ( doc1In: Document | undefined, doc2In: Document | undefined, injectFilterReferences: FilterManager['inject'], - datasourceMap: DatasourceMap + datasourceMap: DatasourceMap, + visualizationMap: VisualizationMap, + annotationGroups: AnnotationGroups ) => { if (doc1In === undefined || doc2In === undefined) { return doc1In === doc2In; @@ -36,7 +38,23 @@ export const isLensEqual = ( return false; } - if (!isEqual(doc1.state.visualization, doc2.state.visualization)) { + const isEqualFromVis = visualizationMap[doc1.visualizationType]?.isEqual; + const visualizationStateIsEqual = isEqualFromVis + ? (() => { + try { + return isEqualFromVis( + doc1.state.visualization, + doc1.references, + doc2.state.visualization, + doc2.references, + annotationGroups + ); + } catch (err) { + return false; + } + })() + : isEqual(doc1.state.visualization, doc2.state.visualization); + if (!visualizationStateIsEqual) { return false; } diff --git a/x-pack/plugins/lens/public/app_plugin/mounter.tsx b/x-pack/plugins/lens/public/app_plugin/mounter.tsx index da790f334f108..9b77ad9d589f4 100644 --- a/x-pack/plugins/lens/public/app_plugin/mounter.tsx +++ b/x-pack/plugins/lens/public/app_plugin/mounter.tsx @@ -96,6 +96,7 @@ export async function getLensServices( inspector, navigation, embeddable, + eventAnnotation, savedObjectsTagging, usageCollection, fieldFormats, @@ -107,6 +108,7 @@ export async function getLensServices( const storage = new Storage(localStorage); const stateTransfer = embeddable?.getStateTransfer(); const embeddableEditorIncomingState = stateTransfer?.getIncomingEditorState(APP_ID); + const eventAnnotationService = await eventAnnotation.getService(); return { data, @@ -118,6 +120,7 @@ export async function getLensServices( usageCollection, savedObjectsTagging, attributeService, + eventAnnotationService, executionContext: coreStart.executionContext, http: coreStart.http, uiActions: startDependencies.uiActions, diff --git a/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts b/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts index a181cea794584..5b6712ed23862 100644 --- a/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts +++ b/x-pack/plugins/lens/public/app_plugin/show_underlying_data.ts @@ -25,7 +25,10 @@ import { showMemoizedErrorNotification } from '../lens_ui_errors'; import { TableInspectorAdapter } from '../editor_frame_service/types'; import { Datasource, DatasourcePublicAPI, IndexPatternMap } from '../types'; import { Visualization } from '..'; -import { getLayerType } from '../editor_frame_service/editor_frame/config_panel/add_layer'; + +function getLayerType(visualization: Visualization, state: unknown, layerId: string) { + return visualization.getLayerType(layerId, state) || LayerTypes.DATA; +} /** * Joins a series of queries. diff --git a/x-pack/plugins/lens/public/app_plugin/tags_saved_object_save_modal_dashboard_wrapper.tsx b/x-pack/plugins/lens/public/app_plugin/tags_saved_object_save_modal_dashboard_wrapper.tsx index 761f46cbbd2c9..39c2f55bdd676 100644 --- a/x-pack/plugins/lens/public/app_plugin/tags_saved_object_save_modal_dashboard_wrapper.tsx +++ b/x-pack/plugins/lens/public/app_plugin/tags_saved_object_save_modal_dashboard_wrapper.tsx @@ -43,6 +43,7 @@ export const TagEnhancedSavedObjectSaveModalDashboard: FC< ) : undefined, [savedObjectsTagging, initialTags] diff --git a/x-pack/plugins/lens/public/app_plugin/types.ts b/x-pack/plugins/lens/public/app_plugin/types.ts index a1b68fb1b4336..142d24f645465 100644 --- a/x-pack/plugins/lens/public/app_plugin/types.ts +++ b/x-pack/plugins/lens/public/app_plugin/types.ts @@ -45,6 +45,7 @@ import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import type { SharePluginStart } from '@kbn/share-plugin/public'; +import type { EventAnnotationServiceType } from '@kbn/event-annotation-plugin/public'; import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import type { DatasourceMap, @@ -148,6 +149,7 @@ export interface LensAppServices { dataViews: DataViewsPublicPluginStart; fieldFormats: FieldFormatsStart; data: DataPublicPluginStart; + eventAnnotationService: EventAnnotationServiceType; inspector: LensInspector; uiSettings: IUiSettingsClient; settings: SettingsStart; diff --git a/x-pack/plugins/lens/public/data_views_service/service.ts b/x-pack/plugins/lens/public/data_views_service/service.ts index 5192de1d2385e..217d621b0ee98 100644 --- a/x-pack/plugins/lens/public/data_views_service/service.ts +++ b/x-pack/plugins/lens/public/data_views_service/service.ts @@ -8,20 +8,18 @@ import type { DataViewsContract, DataView, DataViewSpec } from '@kbn/data-views-plugin/public'; import type { CoreStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; -import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { ActionExecutionContext, UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { UPDATE_FILTER_REFERENCES_ACTION, UPDATE_FILTER_REFERENCES_TRIGGER, } from '@kbn/unified-search-plugin/public'; -import type { IndexPattern, IndexPatternMap, IndexPatternRef } from '../types'; -import { ensureIndexPattern, loadIndexPatternRefs, loadIndexPatterns } from './loader'; +import type { IndexPattern, IndexPatternMap } from '../types'; +import { ensureIndexPattern, loadIndexPatterns } from './loader'; import type { DataViewsState } from '../state_management'; import { generateId } from '../id_generator'; export interface IndexPatternServiceProps { core: Pick; - data: DataPublicPluginStart; dataViews: DataViewsContract; uiActions: UiActionsStart; contextDataViewSpec?: DataViewSpec; @@ -54,10 +52,7 @@ export interface IndexPatternServiceAPI { cache: IndexPatternMap; onIndexPatternRefresh?: () => void; }) => Promise; - /** - * Load indexPatternRefs with title and ids - */ - loadIndexPatternRefs: (options: { isFullEditor: boolean }) => Promise; + /** * Ensure an indexPattern is loaded in the cache, usually used in conjuction with a indexPattern change action. */ @@ -81,16 +76,15 @@ export interface IndexPatternServiceAPI { ) => void; } -export function createIndexPatternService({ +export const createIndexPatternService = ({ core, dataViews, - data, updateIndexPatterns, replaceIndexPattern, uiActions, contextDataViewSpec, -}: IndexPatternServiceProps): IndexPatternServiceAPI { - const onChangeError = (err: Error) => +}: IndexPatternServiceProps): IndexPatternServiceAPI => { + const showLoadingDataViewError = (err: Error) => core.notifications.toasts.addError(err, { title: i18n.translate('xpack.lens.indexPattern.dataViewLoadError', { defaultMessage: 'Error loading data view', @@ -131,9 +125,7 @@ export function createIndexPatternService({ } as ActionExecutionContext); }, ensureIndexPattern: (args) => - ensureIndexPattern({ onError: onChangeError, dataViews, ...args }), - loadIndexPatternRefs: async ({ isFullEditor }) => - isFullEditor ? loadIndexPatternRefs(dataViews) : [], + ensureIndexPattern({ onError: showLoadingDataViewError, dataViews, ...args }), getDefaultIndex: () => core.uiSettings.get('defaultIndex'), }; -} +}; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx deleted file mode 100644 index 299f2b81fc5bb..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx +++ /dev/null @@ -1,158 +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, { useState, useMemo } from 'react'; -import { - EuiToolTip, - EuiButton, - EuiPopover, - EuiIcon, - EuiContextMenu, - EuiBadge, - EuiFlexItem, - EuiFlexGroup, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { LayerTypes } from '@kbn/expression-xy-plugin/public'; -import type { LayerType } from '../../../../common/types'; -import type { FramePublicAPI, Visualization } from '../../../types'; - -interface AddLayerButtonProps { - visualization: Visualization; - visualizationState: unknown; - onAddLayerClick: (layerType: LayerType) => void; - layersMeta: Pick; -} - -export function getLayerType(visualization: Visualization, state: unknown, layerId: string) { - return visualization.getLayerType(layerId, state) || LayerTypes.DATA; -} - -export function AddLayerButton({ - visualization, - visualizationState, - onAddLayerClick, - layersMeta, -}: AddLayerButtonProps) { - const [showLayersChoice, toggleLayersChoice] = useState(false); - - const supportedLayers = useMemo(() => { - if (!visualization.appendLayer || !visualizationState) { - return null; - } - return visualization - .getSupportedLayers?.(visualizationState, layersMeta) - ?.filter(({ canAddViaMenu: hideFromMenu }) => !hideFromMenu); - }, [visualization, visualizationState, layersMeta]); - - if (supportedLayers == null || !supportedLayers.length) { - return null; - } - if (supportedLayers.length === 1) { - return ( - - onAddLayerClick(supportedLayers[0].type)} - iconType="layers" - > - {i18n.translate('xpack.lens.configPanel.addLayerButton', { - defaultMessage: 'Add layer', - })} - - - ); - } - return ( - toggleLayersChoice(!showLayersChoice)} - iconType="layers" - > - {i18n.translate('xpack.lens.configPanel.addLayerButton', { - defaultMessage: 'Add layer', - })} - - } - isOpen={showLayersChoice} - closePopover={() => toggleLayersChoice(false)} - panelPaddingSize="none" - > - { - return { - toolTipContent, - disabled, - name: - type === LayerTypes.ANNOTATIONS ? ( - - - {label} - - - - - {i18n.translate('xpack.lens.configPanel.experimentalLabel', { - defaultMessage: 'Technical preview', - })} - - - - ) : ( - {label} - ), - className: 'lnsLayerAddButton', - icon: icon && , - ['data-test-subj']: `lnsLayerAddButton-${type}`, - onClick: () => { - onAddLayerClick(type); - toggleLayersChoice(false); - }, - }; - }), - }, - ]} - /> - - ); -} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/drop_targets_utils.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/drop_targets_utils.tsx index fe7df1983f3c8..b1451a3fba8b6 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/drop_targets_utils.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/drop_targets_utils.tsx @@ -35,9 +35,9 @@ export function shouldRemoveSource(source: DragDropIdentifier, dropType: DropTyp ); } -export function onDropForVisualization( +export function onDropForVisualization( props: OnVisDropProps, - activeVisualization: Visualization + activeVisualization: Visualization ) { const { prevState, target, frame, source, group } = props; const { layerId, columnId, groupId } = target; 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 184e7d5724297..78f7246c52e6d 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 @@ -16,6 +16,7 @@ import { mockStoreDeps, MountStoreProps, } from '../../../mocks'; +import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { Visualization } from '../../../types'; import { LayerPanels } from './config_panel'; import { LayerPanel } from './layer_panel'; @@ -25,11 +26,11 @@ import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { generateId } from '../../../id_generator'; import { mountWithProvider } from '../../../mocks'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; -import type { LayerType } from '../../../../common/types'; import { ReactWrapper } from 'enzyme'; import { addLayer } from '../../../state_management'; -import { AddLayerButton } from './add_layer'; import { createIndexPatternServiceMock } from '../../../mocks/data_views_service_mock'; +import { AddLayerButton } from '../../../visualizations/xy/add_layer'; +import { LayerType } from '@kbn/visualizations-plugin/common'; jest.mock('../../../id_generator'); @@ -43,6 +44,11 @@ jest.mock('@kbn/kibana-utils-plugin/public', () => { }; }); +const addNewLayer = (instance: ReactWrapper, type: LayerType = LayerTypes.REFERENCELINE) => + act(() => { + instance.find(`button[data-test-subj="${type}"]`).first().simulate('click'); + }); + const waitMs = (time: number) => new Promise((r) => setTimeout(r, time)); let container: HTMLDivElement | undefined; @@ -117,7 +123,21 @@ describe('ConfigPanel', () => { activeVisualization: { ...visualizationMap.testVis, getLayerIds: () => Object.keys(frame.datasourceLayers), - } as unknown as Visualization, + getAddLayerButtonComponent: (props) => { + return ( + <> + + +
+ +
+ + + + + + + + + + +`; + +exports[`DashboardEmptyScreen renders correctly with readonly and edit mode 1`] = ` +
- - Create content that tells a story about your data. - +
+
+
+
+
+
+
+ +
+
+
+
+

+ This dashboard is empty. +

+
+
+
+ + You need additional privileges to edit this dashboard. + +
+
+
+
+
+
+
+
+
`; exports[`DashboardEmptyScreen renders correctly with readonly mode 1`] = `
-
-
- -
-
-

- This dashboard is empty. -

-
-
- You need additional privileges to edit this dashboard. -
-
+
+
+
+
+ +
+
+
+
+

+ This dashboard is empty. +

+
+
+
+ + You need additional privileges to edit this dashboard. + +
+
+
+
+
+
+
+ +
`; exports[`DashboardEmptyScreen renders correctly with view mode 1`] = `
-
-
- -
-
-

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

-
-
-
-

- Click edit in the menu bar above to start adding panels. -

+
+
+
+
+ +
+
+
+
+

+ Add visualizations to your dashboard +

+
+
+
+ + Enter edit mode, and then start adding your visualizations. + +
+
+
+ +
+
+
+
-
-
+ +
`; diff --git a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.test.tsx b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.test.tsx index 9f5fd97bafb25..439fc43ce8eb0 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.test.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.test.tsx @@ -10,49 +10,76 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { findTestSubject } from '@elastic/eui/lib/test'; +import { buildMockDashboard } from '../../../mocks'; +import { DashboardEmptyScreen } from './dashboard_empty_screen'; import { pluginServices } from '../../../services/plugin_services'; -import { DashboardEmptyScreen, DashboardEmptyScreenProps } from './dashboard_empty_screen'; +import { DashboardContainerContext } from '../../embeddable/dashboard_container'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; -describe('DashboardEmptyScreen', () => { - const DashboardServicesProvider = pluginServices.getContextProvider(); - - const defaultProps = { - onLinkClick: jest.fn(), - }; +pluginServices.getServices().visualizations.getAliases = jest + .fn() + .mockReturnValue([{ name: 'lens' }]); - function mountComponent(props?: Partial) { - const compProps = { ...defaultProps, ...props }; +describe('DashboardEmptyScreen', () => { + function mountComponent(viewMode: ViewMode) { + const dashboardContainer = buildMockDashboard({ viewMode }); return mountWithIntl( - - - + + + ); } test('renders correctly with view mode', () => { - const component = mountComponent(); + const component = mountComponent(ViewMode.VIEW); expect(component.render()).toMatchSnapshot(); - const enterEditModeParagraph = component.find('.dshStartScreen__panelDesc'); - expect(enterEditModeParagraph.length).toBe(1); + + const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite'); + expect(emptyReadWrite.length).toBe(1); + const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly'); + expect(emptyReadOnly.length).toBe(0); + const editingPanel = findTestSubject(component, 'emptyDashboardWidget'); + expect(editingPanel.length).toBe(0); }); test('renders correctly with edit mode', () => { - const component = mountComponent({ isEditMode: true }); + const component = mountComponent(ViewMode.EDIT); expect(component.render()).toMatchSnapshot(); - const paragraph = component.find('.dshStartScreen__panelDesc'); - expect(paragraph.length).toBe(0); - const emptyPanel = findTestSubject(component, 'emptyDashboardWidget'); - expect(emptyPanel.length).toBe(1); + + const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite'); + expect(emptyReadWrite.length).toBe(0); + const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly'); + expect(emptyReadOnly.length).toBe(0); + const editingPanel = findTestSubject(component, 'emptyDashboardWidget'); + expect(editingPanel.length).toBe(1); }); test('renders correctly with readonly mode', () => { pluginServices.getServices().dashboardCapabilities.showWriteControls = false; - const component = mountComponent(); + const component = mountComponent(ViewMode.VIEW); + expect(component.render()).toMatchSnapshot(); + + const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite'); + expect(emptyReadWrite.length).toBe(0); + const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly'); + expect(emptyReadOnly.length).toBe(1); + const editingPanel = findTestSubject(component, 'emptyDashboardWidget'); + expect(editingPanel.length).toBe(0); + }); + + // even when in edit mode, readonly users should not have access to the editing buttons in the empty prompt. + test('renders correctly with readonly and edit mode', () => { + pluginServices.getServices().dashboardCapabilities.showWriteControls = false; + + const component = mountComponent(ViewMode.EDIT); expect(component.render()).toMatchSnapshot(); - const paragraph = component.find('.dshStartScreen__panelDesc'); - expect(paragraph.length).toBe(0); - const emptyPanel = findTestSubject(component, 'emptyDashboardWidget'); - expect(emptyPanel.length).toBe(0); + + const emptyReadWrite = findTestSubject(component, 'dashboardEmptyReadWrite'); + expect(emptyReadWrite.length).toBe(0); + const emptyReadOnly = findTestSubject(component, 'dashboardEmptyReadOnly'); + expect(emptyReadOnly.length).toBe(1); + const editingPanel = findTestSubject(component, 'emptyDashboardWidget'); + expect(editingPanel.length).toBe(0); }); }); diff --git a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx index 74d02cd4234b9..050de4189c279 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx @@ -6,95 +6,153 @@ * Side Public License, v 1. */ -import React from 'react'; -import { I18nProvider } from '@kbn/i18n-react'; +import React, { useCallback, useMemo } from 'react'; +import useObservable from 'react-use/lib/useObservable'; + import { - EuiIcon, - EuiSpacer, - EuiPageContent_Deprecated as EuiPageContent, - EuiPageBody, - EuiPage, - EuiImage, EuiText, - EuiTitle, + EuiImage, + EuiButton, + EuiFlexItem, + EuiFlexGroup, + EuiButtonEmpty, + EuiPageTemplate, } from '@elastic/eui'; +import { METRIC_TYPE } from '@kbn/analytics'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; + import { pluginServices } from '../../../services/plugin_services'; import { emptyScreenStrings } from '../../_dashboard_container_strings'; +import { useDashboardContainer } from '../../embeddable/dashboard_container'; +import { DASHBOARD_UI_METRIC_ID, DASHBOARD_APP_ID } from '../../../dashboard_constants'; -export interface DashboardEmptyScreenProps { - isEditMode?: boolean; -} - -export function DashboardEmptyScreen({ isEditMode }: DashboardEmptyScreenProps) { +export function DashboardEmptyScreen() { const { - dashboardCapabilities: { showWriteControls }, + settings: { + theme: { theme$ }, + }, + usageCollection, + data: { search }, http: { basePath }, - settings: { uiSettings }, + embeddable: { getStateTransfer }, + dashboardCapabilities: { showWriteControls }, + visualizations: { getAliases: getVisTypeAliases }, } = pluginServices.getServices(); - const isReadonlyMode = !showWriteControls; - const IS_DARK_THEME = uiSettings.get('theme:darkMode'); - const emptyStateGraphicURL = IS_DARK_THEME - ? '/plugins/home/assets/welcome_graphic_dark_2x.png' - : '/plugins/home/assets/welcome_graphic_light_2x.png'; + const lensAlias = useMemo( + () => getVisTypeAliases().find(({ name }) => name === 'lens'), + [getVisTypeAliases] + ); - const page = (mainText: string, showAdditionalParagraph?: boolean, additionalText?: string) => { - return ( - - - - - -

{mainText}

-
- {additionalText ? ( - - {additionalText} - - ) : null} - {showAdditionalParagraph ? ( - - -
- -

{emptyScreenStrings.getHowToStartWorkingOnNewDashboardDescription()}

-
-
-
- ) : null} -
-
-
+ const goToLens = useCallback(() => { + if (!lensAlias || !lensAlias.aliasPath) return; + const trackUiMetric = usageCollection.reportUiCounter?.bind( + usageCollection, + DASHBOARD_UI_METRIC_ID ); - }; - const readonlyMode = page( - emptyScreenStrings.getEmptyDashboardTitle(), - false, - emptyScreenStrings.getEmptyDashboardAdditionalPrivilege() + + if (trackUiMetric) { + trackUiMetric(METRIC_TYPE.CLICK, `${lensAlias.name}:create`); + } + getStateTransfer().navigateToEditor(lensAlias.aliasApp, { + path: lensAlias.aliasPath, + state: { + originatingApp: DASHBOARD_APP_ID, + searchSessionId: search.session.getSessionId(), + }, + }); + }, [getStateTransfer, lensAlias, search.session, usageCollection]); + + const dashboardContainer = useDashboardContainer(); + const isDarkTheme = useObservable(theme$)?.darkMode; + const isEditMode = + dashboardContainer.select((state) => state.explicitInput.viewMode) === ViewMode.EDIT; + + // TODO replace these SVGs with versions from EuiIllustration as soon as it becomes available. + const imageUrl = basePath.prepend( + `/plugins/dashboard/assets/${isDarkTheme ? 'dashboards_dark' : 'dashboards_light'}.svg` ); - const viewMode = page(emptyScreenStrings.getFillDashboardTitle(), true); - const editMode = ( -
- - - -

{emptyScreenStrings.getEmptyWidgetTitle()}

-
- + + // If the user ends up in edit mode without write privileges, we shouldn't show the edit prompt. + const showEditPrompt = showWriteControls && isEditMode; + + const emptyPromptTestSubject = (() => { + if (showEditPrompt) return 'emptyDashboardWidget'; + return showWriteControls ? 'dashboardEmptyReadWrite' : 'dashboardEmptyReadOnly'; + })(); + + const title = (() => { + const titleString = showEditPrompt + ? emptyScreenStrings.getEditModeTitle() + : showWriteControls + ? emptyScreenStrings.getViewModeWithPermissionsTitle() + : emptyScreenStrings.getViewModeWithoutPermissionsTitle(); + return

{titleString}

; + })(); + + const body = (() => { + const bodyString = showEditPrompt + ? emptyScreenStrings.getEditModeSubtitle() + : showWriteControls + ? emptyScreenStrings.getViewModeWithPermissionsSubtitle() + : emptyScreenStrings.getViewModeWithoutPermissionsSubtitle(); + return ( - {emptyScreenStrings.getEmptyWidgetDescription()} + {bodyString} + ); + })(); + + const actions = (() => { + if (showEditPrompt) { + return ( + + + goToLens()}> + {emptyScreenStrings.getCreateVisualizationButtonTitle()} + + + + dashboardContainer.addFromLibrary()} + > + {emptyScreenStrings.getAddFromLibraryButtonTitle()} + + + + ); + } + if (showWriteControls) { + return ( + dashboardContainer.dispatch.setViewMode(ViewMode.EDIT)} + > + {emptyScreenStrings.getEditLinkTitle()} + + ); + } + })(); + + return ( +
+ + } + title={title} + body={body} + actions={actions} + titleSize="xs" + color="transparent" + className="dshEmptyWidgetContainer" + /> +
); - const actionableMode = isEditMode ? editMode : viewMode; - return {isReadonlyMode ? readonlyMode : actionableMode}; } diff --git a/src/plugins/dashboard/public/dashboard_container/component/viewport/_dashboard_viewport.scss b/src/plugins/dashboard/public/dashboard_container/component/viewport/_dashboard_viewport.scss index 81fdbadf7632d..7cfd8ec50a6a4 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/viewport/_dashboard_viewport.scss +++ b/src/plugins/dashboard/public/dashboard_container/component/viewport/_dashboard_viewport.scss @@ -18,10 +18,6 @@ padding-bottom: $euiSizeXS; } -.dshDashboardEmptyScreen { - margin-top: $euiSizeS; -} - .dashboardViewport--screenshotMode .controlsWrapper--empty { display:none } diff --git a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx index 07bb9d111cd07..117234a0cceb1 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx @@ -74,6 +74,7 @@ export const DashboardViewportComponent = () => { ref={controlsRoot} /> ) : null} + {panelCount === 0 && }
{ data-description={description} data-shared-items-count={panelCount} > - {panelCount === 0 && ( -
- -
- )}
diff --git a/test/functional/screenshots/baseline/dashboard_controls_dark.png b/test/functional/screenshots/baseline/dashboard_controls_dark.png index ed39115481b868190c06f68492ed9853aad63f13..8cd3d27384c3df5491e178e97ffc5c2f5acc765f 100644 GIT binary patch literal 95445 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 literal 70652 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

1z0H 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 literal 68968 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%0Akrl{9ra~Y--}&*xd}T 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 Date: Thu, 1 Jun 2023 00:48:13 -0400 Subject: [PATCH 12/31] [api-docs] 2023-06-01 Daily api_docs build (#158794) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/355 --- 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_data_migration.mdx | 2 +- api_docs/cloud_defend.devdocs.json | 64 - api_docs/cloud_defend.mdx | 4 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.devdocs.json | 64 - api_docs/cloud_security_posture.mdx | 4 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.devdocs.json | 36 +- api_docs/controls.mdx | 4 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 28 +- 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.devdocs.json | 42 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 30 +- api_docs/deprecations_by_plugin.mdx | 39 +- api_docs/deprecations_by_team.mdx | 4 +- 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.devdocs.json | 8 +- api_docs/embeddable.mdx | 4 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.devdocs.json | 10 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.devdocs.json | 565 ++- api_docs/event_annotation.mdx | 7 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.devdocs.json | 549 ++- api_docs/fleet.mdx | 4 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- .../kbn_content_management_table_list.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 +- .../kbn_core_lifecycle_browser.devdocs.json | 28 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- ...ore_saved_objects_api_browser.devdocs.json | 80 +- .../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_datemath.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_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_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.devdocs.json | 76 + api_docs/kbn_io_ts_utils.mdx | 4 +- 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_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 +- ...ml_data_frame_analytics_utils.devdocs.json | 3080 +++++++++++++++++ .../kbn_ml_data_frame_analytics_utils.mdx | 42 + api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_error_utils.devdocs.json | 4 +- 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_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 +- ...n_securitysolution_data_table.devdocs.json | 16 +- 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.devdocs.json | 14 + api_docs/kbn_text_based_editor.mdx | 4 +- 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_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 | 732 ++-- 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 | 38 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 4 +- api_docs/reporting_export_types.devdocs.json | 96 + api_docs/reporting_export_types.mdx | 30 + api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.devdocs.json | 30 + api_docs/saved_objects.mdx | 4 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- .../saved_objects_tagging_oss.devdocs.json | 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.devdocs.json | 14 + api_docs/text_based_languages.mdx | 4 +- api_docs/threat_intelligence.devdocs.json | 95 - api_docs/threat_intelligence.mdx | 4 +- api_docs/timelines.devdocs.json | 98 +- api_docs/timelines.mdx | 4 +- 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_field_list.devdocs.json | 221 +- api_docs/unified_field_list.mdx | 15 +- 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 +- 545 files changed, 5572 insertions(+), 1663 deletions(-) create mode 100644 api_docs/kbn_ml_data_frame_analytics_utils.devdocs.json create mode 100644 api_docs/kbn_ml_data_frame_analytics_utils.mdx create mode 100644 api_docs/reporting_export_types.devdocs.json create mode 100644 api_docs/reporting_export_types.mdx diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index fd08ad5f2ede1..0c100d157ba58 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-05-31 +date: 2023-06-01 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 71c46f8a05f21..b44cbefbe003d 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-05-31 +date: 2023-06-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 06dfa670ca43c..970c618f3d1ca 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-05-31 +date: 2023-06-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 952ede1074ddd..eb03112af6205 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-05-31 +date: 2023-06-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 a42f53edbbe6e..79b49728fad06 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-05-31 +date: 2023-06-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 b0e2a45028dec..6a7616fc7a0ce 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-05-31 +date: 2023-06-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 4c50a3a423140..4b04e4dc641f6 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-05-31 +date: 2023-06-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 65602f29f29a2..c0fe927e72943 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-05-31 +date: 2023-06-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 32b0749282824..b03759f2a3328 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-05-31 +date: 2023-06-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 efa33864a027b..1b2f87f9db24b 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-05-31 +date: 2023-06-01 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 46699dfefbb54..70c8bc9204045 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-05-31 +date: 2023-06-01 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 4449bde006e77..947f3e192f932 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-05-31 +date: 2023-06-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 709423b0f60bb..bdf4dcdf526e4 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 42855dc9da61c..90e5828981c8a 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.devdocs.json b/api_docs/cloud_defend.devdocs.json index 96fff9bfacc8f..88ea58e59eb72 100644 --- a/api_docs/cloud_defend.devdocs.json +++ b/api_docs/cloud_defend.devdocs.json @@ -49,70 +49,6 @@ ], "returnComment": [], "initialIsOpen": false - }, - { - "parentPluginId": "cloudDefend", - "id": "def-public.getSecuritySolutionNavTab", - "type": "Function", - "tags": [], - "label": "getSecuritySolutionNavTab", - "description": [ - "\nGets the link properties of a Cloud Defend page for navigation in the old security solution navigation." - ], - "signature": [ - "(cloudDefendPage: ", - "CloudDefendPage", - ", basePath: string) => CloudDefendNavTab" - ], - "path": "x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "cloudDefend", - "id": "def-public.getSecuritySolutionNavTab.$1", - "type": "CompoundType", - "tags": [], - "label": "cloudDefendPage", - "description": [ - "the name of the cloud defend page." - ], - "signature": [ - "CloudDefendPage" - ], - "path": "x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "cloudDefend", - "id": "def-public.getSecuritySolutionNavTab.$2", - "type": "string", - "tags": [], - "label": "basePath", - "description": [ - "the base path for links." - ], - "signature": [ - "string" - ], - "path": "x-pack/plugins/cloud_defend/public/common/navigation/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false } ], "interfaces": [ diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index 07bf7d9150ba7..848b4ce773674 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/sec-cloudnative-integrations](https://github.com/orgs/elastic/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 15 | 0 | 4 | 2 | +| 12 | 0 | 4 | 2 | ## Client diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index fce19d3588933..e8443b61573bb 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.devdocs.json b/api_docs/cloud_security_posture.devdocs.json index 05494c188c5b3..5b7a964bf9526 100644 --- a/api_docs/cloud_security_posture.devdocs.json +++ b/api_docs/cloud_security_posture.devdocs.json @@ -49,70 +49,6 @@ ], "returnComment": [], "initialIsOpen": false - }, - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-public.getSecuritySolutionNavTab", - "type": "Function", - "tags": [], - "label": "getSecuritySolutionNavTab", - "description": [ - "\nGets the cloud security posture link properties of a CSP page for navigation in the old security solution navigation." - ], - "signature": [ - "(cloudSecurityPosturePage: ", - "CspPage", - ", basePath: string) => CloudSecurityPostureNavTab" - ], - "path": "x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-public.getSecuritySolutionNavTab.$1", - "type": "CompoundType", - "tags": [], - "label": "cloudSecurityPosturePage", - "description": [ - "the name of the cloud posture page." - ], - "signature": [ - "CspPage" - ], - "path": "x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-public.getSecuritySolutionNavTab.$2", - "type": "string", - "tags": [], - "label": "basePath", - "description": [ - "the base path for links." - ], - "signature": [ - "string" - ], - "path": "x-pack/plugins/cloud_security_posture/public/common/navigation/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false } ], "interfaces": [ diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 433dc21b32315..3eefdbaa5e892 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 17 | 0 | 2 | 2 | +| 14 | 0 | 2 | 2 | ## Client diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 548a5c841df0e..4a6a484b764f6 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-05-31 +date: 2023-06-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 ca77fa97dae69..9a8570a85e115 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.devdocs.json b/api_docs/controls.devdocs.json index 5422625608520..6f51cb684008b 100644 --- a/api_docs/controls.devdocs.json +++ b/api_docs/controls.devdocs.json @@ -1899,7 +1899,7 @@ "signature": [ "{ deselectOption: (payload: string) => void; setSearchString: (payload: string) => void; setAllowExpensiveQueries: (payload: boolean) => void; setPopoverOpen: (payload: boolean) => void; setSort: (payload: Partial<", "OptionsListSortingType", - ">) => void; selectExists: (payload: boolean) => void; selectOption: (payload: string) => void; replaceSelection: (payload: string) => void; clearSelections: (payload: unknown) => void; setExclude: (payload: boolean) => void; clearValidAndInvalidSelections: (payload: unknown) => void; setValidAndInvalidSelections: (payload: { validSelections: string[]; invalidSelections: string[]; }) => void; setLoading: (payload: boolean) => void; setField: (payload: ", + ">) => void; selectExists: (payload: boolean) => void; selectOption: (payload: string) => void; replaceSelection: (payload: string) => void; clearSelections: (payload: unknown) => void; setExclude: (payload: boolean) => void; clearValidAndInvalidSelections: (payload: unknown) => void; setValidAndInvalidSelections: (payload: { validSelections: string[]; invalidSelections: string[]; }) => void; setErrorMessage: (payload: string | undefined) => void; setLoading: (payload: boolean) => void; setField: (payload: ", { "pluginId": "dataViews", "scope": "common", @@ -2091,38 +2091,6 @@ "children": [], "returnComment": [] }, - { - "parentPluginId": "controls", - "id": "def-public.OptionsListEmbeddable.onFatalError", - "type": "Function", - "tags": [], - "label": "onFatalError", - "description": [], - "signature": [ - "(e: Error) => void" - ], - "path": "src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "controls", - "id": "def-public.OptionsListEmbeddable.onFatalError.$1", - "type": "Object", - "tags": [], - "label": "e", - "description": [], - "signature": [ - "Error" - ], - "path": "src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, { "parentPluginId": "controls", "id": "def-public.OptionsListEmbeddable.destroy", @@ -3026,7 +2994,7 @@ "section": "def-common.FieldSpec", "text": "FieldSpec" }, - " | undefined) => void; setDataViewId: (payload: string | undefined) => void; setLoading: (payload: boolean) => void; setMinMax: (payload: { min: string; max: string; }) => void; publishFilters: (payload: ", + " | undefined) => void; setDataViewId: (payload: string | undefined) => void; setErrorMessage: (payload: string | undefined) => void; setLoading: (payload: boolean) => void; setMinMax: (payload: { min: string; max: string; }) => void; publishFilters: (payload: ", { "pluginId": "@kbn/es-query", "scope": "common", diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 70dec2b5e5fc7..59450871347b1 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 306 | 0 | 299 | 14 | +| 304 | 0 | 297 | 14 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 27227ef008971..b4a58a719f428 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-05-31 +date: 2023-06-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 12f31b6486305..01cc2b3671e21 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-05-31 +date: 2023-06-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 5b84e8cbbbff4..4698fa014ebf1 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-05-31 +date: 2023-06-01 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 1938c5fbc5cfd..e57d0b4cf1fbd 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -13490,7 +13490,7 @@ }, { "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/common/utils/field_existing_utils.ts" + "path": "src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts" }, { "plugin": "unifiedFieldList", @@ -13932,14 +13932,6 @@ "plugin": "inputControlVis", "path": "src/plugins/input_control_vis/public/control/range_control_factory.ts" }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, { "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/public/components/controls/field.tsx" @@ -14012,10 +14004,6 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/data_views/data_views.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts" @@ -21128,7 +21116,7 @@ }, { "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/common/utils/field_existing_utils.ts" + "path": "src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts" }, { "plugin": "unifiedFieldList", @@ -21570,14 +21558,6 @@ "plugin": "inputControlVis", "path": "src/plugins/input_control_vis/public/control/range_control_factory.ts" }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, { "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/public/components/controls/field.tsx" @@ -21650,10 +21630,6 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/data_views/data_views.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts" diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 3fe933bdad641..9af7f765a5865 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-05-31 +date: 2023-06-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 56a4b82a8ee30..48548c4d26bc4 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-05-31 +date: 2023-06-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 e4ae53d3e2549..523d6facaf583 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-05-31 +date: 2023-06-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 610834967fe9a..d68a4ecca7ef1 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-05-31 +date: 2023-06-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 48f240e29162a..3f079fcc274a7 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-05-31 +date: 2023-06-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 c60aab9fb755b..10afee3f843a6 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-05-31 +date: 2023-06-01 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 3c4cfa5ab7f35..ffc640dbd60bc 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -329,7 +329,7 @@ }, { "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/common/utils/field_existing_utils.ts" + "path": "src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts" }, { "plugin": "unifiedFieldList", @@ -763,14 +763,6 @@ "plugin": "inputControlVis", "path": "src/plugins/input_control_vis/public/control/range_control_factory.ts" }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, { "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/public/components/controls/field.tsx" @@ -871,10 +863,6 @@ "plugin": "visTypeTimeseries", "path": "src/plugins/vis_types/timeseries/server/lib/search_strategies/lib/cached_index_pattern_fetcher.test.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts" @@ -8613,7 +8601,7 @@ }, { "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/common/utils/field_existing_utils.ts" + "path": "src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts" }, { "plugin": "unifiedFieldList", @@ -9047,14 +9035,6 @@ "plugin": "inputControlVis", "path": "src/plugins/input_control_vis/public/control/range_control_factory.ts" }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, { "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/public/components/controls/field.tsx" @@ -9155,10 +9135,6 @@ "plugin": "visTypeTimeseries", "path": "src/plugins/vis_types/timeseries/server/lib/search_strategies/lib/cached_index_pattern_fetcher.test.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts" @@ -15954,7 +15930,7 @@ }, { "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/common/utils/field_existing_utils.ts" + "path": "src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts" }, { "plugin": "unifiedFieldList", @@ -16388,14 +16364,6 @@ "plugin": "inputControlVis", "path": "src/plugins/input_control_vis/public/control/range_control_factory.ts" }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, - { - "plugin": "unifiedFieldList", - "path": "src/plugins/unified_field_list/server/routes/field_stats.ts" - }, { "plugin": "visDefaultEditor", "path": "src/plugins/vis_default_editor/public/components/controls/field.tsx" @@ -16496,10 +16464,6 @@ "plugin": "visTypeTimeseries", "path": "src/plugins/vis_types/timeseries/server/lib/search_strategies/lib/cached_index_pattern_fetcher.test.ts" }, - { - "plugin": "discover", - "path": "src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts" - }, { "plugin": "infra", "path": "x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts" diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index daa74e90d9a89..b00e17a4962fa 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-05-31 +date: 2023-06-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 05eec42ea7ca2..2eebe14eeb8a3 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-05-31 +date: 2023-06-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 245711187f64c..3480b943678a9 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -17,17 +17,17 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Referencing plugin(s) | Remove By | | ---------------|-----------|-----------| | | ml, stackAlerts | - | -| | @kbn/es-query, visualizationUiComponents, securitySolution, timelines, lists, threatIntelligence, dataViews, savedObjectsManagement, unifiedSearch, controls, unifiedFieldList, lens, triggersActionsUi, aiops, ml, infra, visTypeTimeseries, apm, exploratoryView, dataVisualizer, fleet, canvas, enterpriseSearch, graph, stackAlerts, synthetics, transform, upgradeAssistant, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, discover, data | - | -| | @kbn/es-query, visualizationUiComponents, securitySolution, timelines, lists, threatIntelligence, dataViews, savedObjectsManagement, unifiedSearch, controls, unifiedFieldList, lens, triggersActionsUi, aiops, ml, infra, visTypeTimeseries, apm, exploratoryView, dataVisualizer, fleet, canvas, enterpriseSearch, graph, stackAlerts, synthetics, transform, upgradeAssistant, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, discover, data | - | -| | @kbn/es-query, visualizationUiComponents, securitySolution, timelines, lists, threatIntelligence, data, savedObjectsManagement, unifiedSearch, controls, unifiedFieldList, lens, triggersActionsUi, aiops, ml, infra, visTypeTimeseries, apm, exploratoryView, dataVisualizer, fleet, canvas, enterpriseSearch, graph, stackAlerts, synthetics, transform, upgradeAssistant, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, discover | - | +| | @kbn/es-query, visualizationUiComponents, securitySolution, timelines, lists, threatIntelligence, dataViews, savedObjectsManagement, unifiedSearch, controls, unifiedFieldList, lens, triggersActionsUi, aiops, ml, infra, visTypeTimeseries, apm, exploratoryView, dataVisualizer, fleet, canvas, enterpriseSearch, graph, stackAlerts, synthetics, transform, upgradeAssistant, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | +| | @kbn/es-query, visualizationUiComponents, securitySolution, timelines, lists, threatIntelligence, dataViews, savedObjectsManagement, unifiedSearch, controls, unifiedFieldList, lens, triggersActionsUi, aiops, ml, infra, visTypeTimeseries, apm, exploratoryView, dataVisualizer, fleet, canvas, enterpriseSearch, graph, stackAlerts, synthetics, transform, upgradeAssistant, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | +| | @kbn/es-query, visualizationUiComponents, securitySolution, timelines, lists, threatIntelligence, data, savedObjectsManagement, unifiedSearch, controls, unifiedFieldList, lens, triggersActionsUi, aiops, ml, infra, visTypeTimeseries, apm, exploratoryView, dataVisualizer, fleet, canvas, enterpriseSearch, graph, stackAlerts, synthetics, transform, upgradeAssistant, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega | - | | | home, data, esUiShared, spaces, savedObjectsManagement, exploratoryView, fleet, observability, ml, apm, indexLifecycleManagement, observabilityOnboarding, synthetics, upgradeAssistant, ux, kibanaOverview | - | | | encryptedSavedObjects, actions, data, ml, logstash, securitySolution, cloudChat | - | | | actions, ml, savedObjectsTagging, enterpriseSearch | - | -| | @kbn/core-plugins-browser-internal, @kbn/core-root-browser-internal, dataViews, home, data, savedObjects, unifiedSearch, presentationUtil, visualizations, dashboard, lens, discover, fileUpload, ml, fleet, canvas, dashboardEnhanced, monitoring, synthetics, transform, dataVisualizer, cloudSecurityPosture | - | -| | @kbn/core-saved-objects-browser, @kbn/core-saved-objects-browser-internal, @kbn/core, dataViews, home, savedObjects, savedSearch, visualizations, dashboard, lens, ml, canvas, visTypeTimeseries, @kbn/core-saved-objects-browser-mocks | - | -| | @kbn/core-saved-objects-browser-mocks, savedObjects, presentationUtil, savedSearch, dashboard, ml, cloudSecurityPosture, dashboardEnhanced, @kbn/core-saved-objects-browser-internal | - | -| | @kbn/core-saved-objects-browser-mocks, dataViews, savedObjects, dashboard, ml, cloudSecurityPosture, dashboardEnhanced, monitoring, @kbn/core-saved-objects-browser-internal | - | -| | @kbn/core-saved-objects-browser-internal, @kbn/core, savedObjects, embeddable, presentationUtil, visualizations, dashboard, aiops, ml, dataVisualizer, fleet, cloudSecurityPosture, dashboardEnhanced, graph, synthetics, lens, securitySolution, @kbn/core-saved-objects-browser-mocks | - | +| | @kbn/core-plugins-browser-internal, @kbn/core-root-browser-internal, dataViews, home, data, savedObjects, unifiedSearch, presentationUtil, visualizations, dashboard, eventAnnotation, lens, discover, fileUpload, ml, fleet, canvas, dashboardEnhanced, monitoring, synthetics, transform, dataVisualizer | - | +| | @kbn/core-saved-objects-browser, @kbn/core-saved-objects-browser-internal, @kbn/core, dataViews, home, savedObjects, savedSearch, visualizations, dashboard, eventAnnotation, lens, ml, canvas, visTypeTimeseries, @kbn/core-saved-objects-browser-mocks | - | +| | @kbn/core-saved-objects-browser-mocks, savedObjects, presentationUtil, savedSearch, dashboard, eventAnnotation, ml, dashboardEnhanced, @kbn/core-saved-objects-browser-internal | - | +| | @kbn/core-saved-objects-browser-mocks, dataViews, savedObjects, dashboard, eventAnnotation, ml, dashboardEnhanced, monitoring, @kbn/core-saved-objects-browser-internal | - | +| | @kbn/core-saved-objects-browser-internal, @kbn/core, savedObjects, embeddable, presentationUtil, visualizations, dashboard, aiops, ml, dataVisualizer, fleet, dashboardEnhanced, graph, synthetics, lens, securitySolution, eventAnnotation, @kbn/core-saved-objects-browser-mocks | - | | | @kbn/core-lifecycle-browser-mocks, @kbn/core, ml, dashboard, dataViews, savedSearch, @kbn/core-plugins-browser-internal | - | | | @kbn/core, savedObjects, embeddable, visualizations, dashboard, fleet, canvas, graph, ml, @kbn/core-saved-objects-common, @kbn/core-saved-objects-server, actions, alerting, savedSearch, enterpriseSearch, securitySolution, taskManager, @kbn/core-saved-objects-server-internal, @kbn/core-saved-objects-api-server | - | | | stackAlerts, alerting, securitySolution, inputControlVis | - | @@ -64,14 +64,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | securitySolution | - | | | securitySolution | - | | | monitoring | - | -| | @kbn/core-saved-objects-api-browser, @kbn/core, savedObjects, savedObjectsManagement, visualizations, savedObjectsTagging, lens, fleet, graph, dashboard, savedObjectsTaggingOss, kibanaUtils, expressions, dataViews, data, embeddable, controls, uiActionsEnhanced, cases, maps, canvas, dashboardEnhanced, globalSearchProviders, infra | - | -| | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedObjects, savedSearch, dashboard | - | -| | @kbn/core-saved-objects-browser-mocks, home, @kbn/core-saved-objects-browser-internal | - | +| | @kbn/core-saved-objects-api-browser, @kbn/core, savedObjects, savedObjectsManagement, visualizations, eventAnnotation, savedObjectsTagging, lens, fleet, graph, dashboard, savedObjectsTaggingOss, kibanaUtils, expressions, dataViews, data, embeddable, controls, uiActionsEnhanced, cases, maps, canvas, dashboardEnhanced, globalSearchProviders, infra | - | +| | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedObjects, savedSearch, dashboard, eventAnnotation | - | +| | @kbn/core-saved-objects-browser-mocks, home, eventAnnotation, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedObjects, visualizations, dashboard | - | | | @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-mocks, dashboard, savedObjects, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-mocks, fleet, synthetics, @kbn/core-saved-objects-browser-internal | - | -| | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedSearch, savedObjects | - | +| | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedSearch, eventAnnotation, savedObjects | - | | | @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-internal | - | @@ -80,7 +80,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-api-server-internal, canvas | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core | - | -| | @kbn/core-saved-objects-browser-internal, @kbn/core, cloudSecurityPosture | - | +| | @kbn/core-saved-objects-browser-internal, @kbn/core | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core, spaces, savedSearch, visualizations, dashboard, lens, cases, maps, fleet, canvas, graph | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core | - | @@ -135,7 +135,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | security, licenseManagement, ml, apm, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher, profiling | 8.8.0 | | | spaces, security, actions, alerting, ml, remoteClusters, graph, indexLifecycleManagement, mapsEms, osquery, painlessLab, rollup, searchprofiler, securitySolution, snapshotRestore, transform, upgradeAssistant | 8.8.0 | | | spaces, security, alerting | 8.8.0 | -| | embeddable, presentationUtil, dashboard, discover, graph | 8.8.0 | +| | embeddable, presentationUtil, dashboard, lens, discover, graph | 8.8.0 | | | apm, security, securitySolution | 8.8.0 | | | apm, security, securitySolution | 8.8.0 | | | @kbn/core-application-browser-internal, @kbn/core-application-browser-mocks, management, fleet, security, kibanaOverview, @kbn/core | 8.8.0 | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index e9d7a56019f34..f0b9c7258ef23 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -434,11 +434,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [overview_tab.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/overview_tab.tsx#:~:text=indexPatternId) | - | -| | [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=savedObjects) | - | -| | [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=find) | - | -| | [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=get) | - | -| | [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=SimpleSavedObject), [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=SimpleSavedObject), [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=SimpleSavedObject) | - | -| | [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=SavedObjectsFindOptions), [use_csp_rules.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts#:~:text=SavedObjectsFindOptions) | - | @@ -585,11 +580,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create) | - | -| | [use_text_based_query_language.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts#:~:text=title), [use_text_based_query_language.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts#:~:text=title) | - | | | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create) | - | | | [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts#:~:text=EsQuerySearchAfter), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts#:~:text=EsQuerySearchAfter), [get_es_query_search_after.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/context/utils/get_es_query_search_after.ts#:~:text=EsQuerySearchAfter), [get_es_query_search_after.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/context/utils/get_es_query_search_after.ts#:~:text=EsQuerySearchAfter), [get_es_query_search_after.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/context/utils/get_es_query_search_after.ts#:~:text=EsQuerySearchAfter) | - | -| | [use_text_based_query_language.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts#:~:text=title), [use_text_based_query_language.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts#:~:text=title) | - | -| | [use_text_based_query_language.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts#:~:text=title) | - | | | [on_save_search.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [on_save_search.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | | | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=executeTriggerActions), [search_embeddable_factory.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/embeddable/search_embeddable_factory.ts#:~:text=executeTriggerActions), [plugin.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/plugin.tsx#:~:text=executeTriggerActions) | - | | | [discover_saved_search_container.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/services/discover_saved_search_container.ts#:~:text=savedObjects), [discover_saved_search_container.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/services/discover_saved_search_container.ts#:~:text=savedObjects), [search_embeddable_factory.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/embeddable/search_embeddable_factory.ts#:~:text=savedObjects), [discover_saved_search_container.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/services/discover_saved_search_container.test.ts#:~:text=savedObjects), [discover_state.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/discover/public/application/main/services/discover_state.test.ts#:~:text=savedObjects) | - | @@ -648,6 +640,22 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] +## eventAnnotation + +| Deprecated API | Reference location(s) | Remove By | +| ---------------|-----------|-----------| +| | [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=savedObjects), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=savedObjects), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=savedObjects), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=savedObjects), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=savedObjects), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=savedObjects) | - | +| | [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=SavedObjectsClientContract), [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=SavedObjectsClientContract) | - | +| | [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=create), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=create), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=create) | - | +| | [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=bulkCreate) | - | +| | [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=find) | - | +| | [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=get), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=get) | - | +| | [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=update), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=update) | - | +| | [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=SimpleSavedObject), [service.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.test.ts#:~:text=SimpleSavedObject) | - | +| | [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=SavedObjectReference), [service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/event_annotation/public/event_annotation_service/service.tsx#:~:text=SavedObjectReference) | - | + + + ## exploratoryView | Deprecated API | Reference location(s) | Remove By | @@ -821,12 +829,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title), [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title) | - | | | [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title), [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title) | - | | | [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title) | - | +| | [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | | | [form_based.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx#:~:text=savedObjects), [form_based.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx#:~:text=savedObjects), [form_based.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx#:~:text=savedObjects), [visualization.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx#:~:text=savedObjects), [visualization.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx#:~:text=savedObjects), [visualization.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx#:~:text=savedObjects) | - | | | [reference_editor.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx#:~:text=SavedObjectsClientContract), [reference_editor.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx#:~:text=SavedObjectsClientContract), [dimension_panel.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.tsx#:~:text=SavedObjectsClientContract), [dimension_panel.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.tsx#:~:text=SavedObjectsClientContract), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts#:~:text=SavedObjectsClientContract), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts#:~:text=SavedObjectsClientContract), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract) | - | | | [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SimpleSavedObject), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SimpleSavedObject) | - | | | [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject) | - | | | [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=simpleSavedObjectMock), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=simpleSavedObjectMock) | - | -| | [saved_object_store.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_object_store.ts#:~:text=SavedObjectReference), [saved_object_store.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_object_store.ts#:~:text=SavedObjectReference), [saved_object_store.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_object_store.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [selectors.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/state_management/selectors.ts#:~:text=SavedObjectReference)+ 43 more | - | +| | [saved_object_store.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_object_store.ts#:~:text=SavedObjectReference), [saved_object_store.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_object_store.ts#:~:text=SavedObjectReference), [saved_object_store.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_object_store.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference), [state_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts#:~:text=SavedObjectReference)+ 48 more | - | | | [saved_objects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/server/saved_objects.ts#:~:text=convertToMultiNamespaceTypeVersion) | - | @@ -1132,8 +1141,8 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [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 | | | [request_context_factory.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=authc), [route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts#:~:text=authc), [create_signals_migration_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts#:~:text=authc), [delete_signals_migration_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts#:~:text=authc), [finalize_signals_migration_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts#:~:text=authc), [open_close_signals_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts#:~:text=authc), [common.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts#:~:text=authc) | - | | | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BeatFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=BeatFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=BeatFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=BeatFields) | - | -| | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [use_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx#:~:text=BrowserField)+ 34 more | - | -| | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields)+ 99 more | - | +| | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [columns.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [enrichment_summary.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/enrichment_summary.tsx#:~:text=BrowserField), [use_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx#:~:text=BrowserField)+ 31 more | - | +| | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/header_actions/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/lib/kuery/index.ts#:~:text=BrowserFields)+ 100 more | - | | | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyRequest), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyRequest), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyRequest) | - | | | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/search_strategy/index_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/search_strategy/endpoint_fields/index.ts#:~:text=IndexFieldsStrategyResponse), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyResponse), [middleware.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=IndexFieldsStrategyResponse) | - | | | [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/hooks/types.ts#:~:text=SimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/hooks/types.ts#:~:text=SimpleSavedObject) | - | @@ -1270,9 +1279,9 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/common/utils/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/server/routes/field_stats.ts#:~:text=title), [field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/server/routes/field_stats.ts#:~:text=title), [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/common/utils/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title)+ 2 more | - | -| | [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/common/utils/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/server/routes/field_stats.ts#:~:text=title), [field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/server/routes/field_stats.ts#:~:text=title), [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/common/utils/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title)+ 2 more | - | -| | [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/common/utils/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/server/routes/field_stats.ts#:~:text=title), [field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/server/routes/field_stats.ts#:~:text=title) | - | +| | [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title) | - | +| | [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title) | - | +| | [load_field_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_stats/load_field_stats.ts#:~:text=title), [field_existing_utils.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/services/field_existing/field_existing_utils.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title), [use_existing_fields.ts](https://github.com/elastic/kibana/tree/main/src/plugins/unified_field_list/public/hooks/use_existing_fields.ts#:~:text=title) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 0545c9da52328..5fe7fe3cc19e7 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -102,7 +102,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| | graph | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/server/plugin.ts#:~:text=license%24) | 8.8.0 | -| graph | | [save_modal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | +| graph | | [save_modal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 3c49423dd0c49..534c42451770a 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-05-31 +date: 2023-06-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 f4efe35217298..5e8ee2dbb90b0 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-05-31 +date: 2023-06-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 ba3e9d46733b9..904642234936d 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-05-31 +date: 2023-06-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 9fe66a76cb644..c10d94ce5289b 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index 1d2998c46bd41..ead5399485a42 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -3238,7 +3238,9 @@ "type": "Function", "tags": [], "label": "onFatalError", - "description": [], + "description": [ + "\nCall this **only** when your embeddable has encountered a non-recoverable error; recoverable errors\nshould be handled by the individual embeddable types" + ], "signature": [ "(e: Error) => void" ], @@ -3252,7 +3254,9 @@ "type": "Object", "tags": [], "label": "e", - "description": [], + "description": [ + "The fatal, unrecoverable Error that was thrown" + ], "signature": [ "Error" ], diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 65407e2707638..f35c012a37d2a 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 546 | 11 | 444 | 4 | +| 546 | 11 | 442 | 4 | ## Client diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 3fe195efefaee..9db517903047e 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-05-31 +date: 2023-06-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 87e89a93e9c94..596a837dd0b7f 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.devdocs.json b/api_docs/enterprise_search.devdocs.json index 47c6d7ad5017e..2e651ea7e7064 100644 --- a/api_docs/enterprise_search.devdocs.json +++ b/api_docs/enterprise_search.devdocs.json @@ -38,7 +38,7 @@ "label": "ConfigType", "description": [], "signature": [ - "{ readonly host?: string | undefined; readonly customHeaders?: Readonly<{} & {}> | undefined; readonly enabled: boolean; readonly ssl: Readonly<{ certificateAuthorities?: string | string[] | undefined; } & { verificationMode: \"none\" | \"full\" | \"certificate\"; }>; readonly accessCheckTimeout: number; readonly accessCheckTimeoutWarning: number; readonly canDeployEntSearch: boolean; readonly hasConnectors: boolean; readonly hasDefaultIngestPipeline: boolean; readonly hasDocumentLevelSecurityEnabled: boolean; readonly hasNativeConnectors: boolean; readonly hasWebCrawler: boolean; }" + "{ readonly host?: string | undefined; readonly customHeaders?: Readonly<{} & {}> | undefined; readonly enabled: boolean; readonly ssl: Readonly<{ certificateAuthorities?: string | string[] | undefined; } & { verificationMode: \"none\" | \"full\" | \"certificate\"; }>; readonly accessCheckTimeout: number; readonly accessCheckTimeoutWarning: number; readonly canDeployEntSearch: boolean; readonly hasConnectors: boolean; readonly hasDefaultIngestPipeline: boolean; readonly hasDocumentLevelSecurityEnabled: boolean; readonly hasIncrementalSyncEnabled: boolean; readonly hasNativeConnectors: boolean; readonly hasWebCrawler: boolean; }" ], "path": "x-pack/plugins/enterprise_search/server/index.ts", "deprecated": false, @@ -201,6 +201,14 @@ "section": "def-common.Type", "text": "Type" }, + "; hasIncrementalSyncEnabled: ", + { + "pluginId": "@kbn/config-schema", + "scope": "common", + "docId": "kibKbnConfigSchemaPluginApi", + "section": "def-common.Type", + "text": "Type" + }, "; hasNativeConnectors: ", { "pluginId": "@kbn/config-schema", diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index b923a1881aea5..5b7099098c397 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-05-31 +date: 2023-06-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 e0034c98b06ea..7f5258e34e4c1 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.devdocs.json b/api_docs/event_annotation.devdocs.json index 3ca7a31c9bd78..0af88a4d3a6c1 100644 --- a/api_docs/event_annotation.devdocs.json +++ b/api_docs/event_annotation.devdocs.json @@ -181,6 +181,153 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.loadAnnotationGroup", + "type": "Function", + "tags": [], + "label": "loadAnnotationGroup", + "description": [], + "signature": [ + "(savedObjectId: string) => Promise<", + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + }, + ">" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.loadAnnotationGroup.$1", + "type": "string", + "tags": [], + "label": "savedObjectId", + "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.createAnnotationGroup", + "type": "Function", + "tags": [], + "label": "createAnnotationGroup", + "description": [], + "signature": [ + "(group: ", + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + }, + ") => Promise<{ id: string; }>" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.createAnnotationGroup.$1", + "type": "Object", + "tags": [], + "label": "group", + "description": [], + "signature": [ + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + } + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.updateAnnotationGroup", + "type": "Function", + "tags": [], + "label": "updateAnnotationGroup", + "description": [], + "signature": [ + "(group: ", + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + }, + ", savedObjectId: string) => Promise" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.updateAnnotationGroup.$1", + "type": "Object", + "tags": [], + "label": "group", + "description": [], + "signature": [ + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + } + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.updateAnnotationGroup.$2", + "type": "string", + "tags": [], + "label": "savedObjectId", + "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.toExpression", @@ -244,7 +391,7 @@ "label": "toFetchExpression", "description": [], "signature": [ - "(props: { interval: string; groups: ", + "(props: { interval: string; groups: Pick<", { "pluginId": "eventAnnotation", "scope": "common", @@ -252,7 +399,7 @@ "section": "def-common.EventAnnotationGroupConfig", "text": "EventAnnotationGroupConfig" }, - "[]; }) => ", + ", \"annotations\" | \"ignoreGlobalFilters\" | \"indexPatternId\">[]; }) => ", { "pluginId": "expressions", "scope": "common", @@ -296,6 +443,7 @@ "label": "groups", "description": [], "signature": [ + "Pick<", { "pluginId": "eventAnnotation", "scope": "common", @@ -303,7 +451,7 @@ "section": "def-common.EventAnnotationGroupConfig", "text": "EventAnnotationGroupConfig" }, - "[]" + ", \"annotations\" | \"ignoreGlobalFilters\" | \"indexPatternId\">[]" ], "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", "deprecated": false, @@ -313,6 +461,166 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder", + "type": "Function", + "tags": [], + "label": "renderEventAnnotationGroupSavedObjectFinder", + "description": [], + "signature": [ + "(props: { fixedPageSize?: number | undefined; onChoose: (value: { id: string; type: string; fullName: string; savedObject: ", + { + "pluginId": "savedObjectsFinder", + "scope": "common", + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.SavedObjectCommon", + "text": "SavedObjectCommon" + }, + "; }) => void; onCreateNew: () => void; }) => JSX.Element" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.fixedPageSize", + "type": "number", + "tags": [], + "label": "fixedPageSize", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.onChoose", + "type": "Function", + "tags": [], + "label": "onChoose", + "description": [], + "signature": [ + "(value: { id: string; type: string; fullName: string; savedObject: ", + { + "pluginId": "savedObjectsFinder", + "scope": "common", + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.SavedObjectCommon", + "text": "SavedObjectCommon" + }, + "; }) => void" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.onChoose.$1", + "type": "Object", + "tags": [], + "label": "value", + "description": [], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.onChoose.$1.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.onChoose.$1.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.onChoose.$1.fullName", + "type": "string", + "tags": [], + "label": "fullName", + "description": [], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.onChoose.$1.savedObject", + "type": "Object", + "tags": [], + "label": "savedObject", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObject", + "text": "SavedObject" + }, + "" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [] + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationServiceType.renderEventAnnotationGroupSavedObjectFinder.$1.onCreateNew", + "type": "Function", + "tags": [], + "label": "onCreateNew", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ] + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -349,6 +657,22 @@ } ], "objects": [], + "setup": { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationPluginSetup", + "type": "Type", + "tags": [], + "label": "EventAnnotationPluginSetup", + "description": [], + "signature": [ + "void" + ], + "path": "src/plugins/event_annotation/public/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "lifecycle": "setup", + "initialIsOpen": true + }, "start": { "parentPluginId": "eventAnnotation", "id": "def-public.EventAnnotationService", @@ -360,6 +684,65 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationService.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/index.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationService.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "core", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-lifecycle-browser", + "scope": "common", + "docId": "kibKbnCoreLifecycleBrowserPluginApi", + "section": "def-common.CoreStart", + "text": "CoreStart" + } + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/index.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-public.EventAnnotationService.Unnamed.$2", + "type": "Object", + "tags": [], + "label": "savedObjectsManagement", + "description": [], + "signature": [ + { + "pluginId": "savedObjectsManagement", + "scope": "public", + "docId": "kibSavedObjectsManagementPluginApi", + "section": "def-public.SavedObjectsManagementPluginStart", + "text": "SavedObjectsManagementPluginStart" + } + ], + "path": "src/plugins/event_annotation/public/event_annotation_service/index.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "eventAnnotation", "id": "def-public.EventAnnotationService.getService", @@ -527,6 +910,109 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupAttributes", + "type": "Interface", + "tags": [], + "label": "EventAnnotationGroupAttributes", + "description": [], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupAttributes.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupAttributes.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupAttributes.tags", + "type": "Array", + "tags": [], + "label": "tags", + "description": [], + "signature": [ + "string[]" + ], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupAttributes.ignoreGlobalFilters", + "type": "boolean", + "tags": [], + "label": "ignoreGlobalFilters", + "description": [], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupAttributes.annotations", + "type": "Array", + "tags": [], + "label": "annotations", + "description": [], + "signature": [ + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationConfig", + "text": "EventAnnotationConfig" + }, + "[]" + ], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupAttributes.dataViewSpec", + "type": "Object", + "tags": [], + "label": "dataViewSpec", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" + }, + " | undefined" + ], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "eventAnnotation", "id": "def-common.EventAnnotationGroupConfig", @@ -573,12 +1059,66 @@ { "parentPluginId": "eventAnnotation", "id": "def-common.EventAnnotationGroupConfig.ignoreGlobalFilters", - "type": "CompoundType", + "type": "boolean", "tags": [], "label": "ignoreGlobalFilters", "description": [], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupConfig.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupConfig.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupConfig.tags", + "type": "Array", + "tags": [], + "label": "tags", + "description": [], "signature": [ - "boolean | undefined" + "string[]" + ], + "path": "src/plugins/event_annotation/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EventAnnotationGroupConfig.dataViewSpec", + "type": "Object", + "tags": [], + "label": "dataViewSpec", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" + }, + " | undefined" ], "path": "src/plugins/event_annotation/common/types.ts", "deprecated": false, @@ -645,6 +1185,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "eventAnnotation", + "id": "def-common.EVENT_ANNOTATION_GROUP_TYPE", + "type": "string", + "tags": [], + "label": "EVENT_ANNOTATION_GROUP_TYPE", + "description": [], + "signature": [ + "\"event-annotation-group\"" + ], + "path": "src/plugins/event_annotation/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "eventAnnotation", "id": "def-common.EventAnnotationArgs", diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index d18e0f905a533..715e82c02259e 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; @@ -21,10 +21,13 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 172 | 30 | 172 | 3 | +| 204 | 30 | 204 | 3 | ## Client +### Setup + + ### Start diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 0bc650de650f3..2d5b7b804a683 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-05-31 +date: 2023-06-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 ff6ccf993b4fc..61505217772cd 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-05-31 +date: 2023-06-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 ca3d17515aa25..edddeebb52614 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-05-31 +date: 2023-06-01 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 bf1a304247354..c86241bbb321a 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-05-31 +date: 2023-06-01 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 03177790ae19b..be69fb06ecb81 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-05-31 +date: 2023-06-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 5f421f97c3ecb..e3ebb9ea90ae8 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-05-31 +date: 2023-06-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 149c81599066c..4e7893ddb4cf3 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-05-31 +date: 2023-06-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 adb9d5c2fad73..3f5dd34f00308 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-05-31 +date: 2023-06-01 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 c2b9931fd75d6..160dec01b67a8 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-05-31 +date: 2023-06-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 850506b609e72..1689d71fe4179 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-05-31 +date: 2023-06-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 4f07d20c9c438..c9c04284fb55a 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-05-31 +date: 2023-06-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 03e81a2fc6256..2d6b5049d486a 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-05-31 +date: 2023-06-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 dc3923cb3235c..ea152016231f9 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-05-31 +date: 2023-06-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 dac92c8a836c3..d0c981ff516b5 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-05-31 +date: 2023-06-01 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 9a46e3e885420..4eff9cb27ea99 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-05-31 +date: 2023-06-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 1a84da3285db2..b1c3a3ae0ed64 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-05-31 +date: 2023-06-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 ca477ab27f538..19bc10ba3a08c 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-05-31 +date: 2023-06-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 26569de43225c..9b8d8264b1052 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-05-31 +date: 2023-06-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 c73e356a0d0f2..fb3a42ea893df 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-05-31 +date: 2023-06-01 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 55ed092d65485..2bdd8025b753d 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-05-31 +date: 2023-06-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 72e2e0a760300..4f8855b9b96c3 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index 22997a28a93f3..683899e123e9d 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -5660,10 +5660,10 @@ }, { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface", + "id": "def-server.FleetFileUpdatableFields", "type": "Interface", "tags": [], - "label": "FleetFileClientInterface", + "label": "FleetFileUpdatableFields", "description": [], "path": "x-pack/plugins/fleet/server/services/files/types.ts", "deprecated": false, @@ -5671,185 +5671,48 @@ "children": [ { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.create", - "type": "Function", - "tags": [], - "label": "create", - "description": [ - "Creates a new file. Only applicable when type of file is `to-host`." - ], - "signature": [ - "(fileStream: ", - { - "pluginId": "fleet", - "scope": "server", - "docId": "kibFleetPluginApi", - "section": "def-server.HapiReadableStream", - "text": "HapiReadableStream" - }, - ", agentIds: string[]) => Promise<", - { - "pluginId": "fleet", - "scope": "server", - "docId": "kibFleetPluginApi", - "section": "def-server.FleetFile", - "text": "FleetFile" - }, - ">" - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.create.$1", - "type": "Object", - "tags": [], - "label": "fileStream", - "description": [], - "signature": [ - { - "pluginId": "fleet", - "scope": "server", - "docId": "kibFleetPluginApi", - "section": "def-server.HapiReadableStream", - "text": "HapiReadableStream" - } - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.create.$2", - "type": "Array", - "tags": [], - "label": "agentIds", - "description": [], - "signature": [ - "string[]" - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.delete", - "type": "Function", + "id": "def-server.FleetFileUpdatableFields.agents", + "type": "Array", "tags": [], - "label": "delete", - "description": [ - "Deletes a file. Only applicable when type of file is `to-host`." - ], + "label": "agents", + "description": [], "signature": [ - "(fileId: string) => Promise" + "string[]" ], "path": "x-pack/plugins/fleet/server/services/files/types.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.delete.$1", - "type": "string", - "tags": [], - "label": "fileId", - "description": [], - "signature": [ - "string" - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.update", - "type": "Function", + "id": "def-server.FleetFileUpdatableFields.actionId", + "type": "string", "tags": [], - "label": "update", - "description": [ - "Updates metadata for the file. Only applicable when type of file is `to-host`." - ], - "signature": [ - "(fileId: string, updates: Partial<", - { - "pluginId": "fleet", - "scope": "server", - "docId": "kibFleetPluginApi", - "section": "def-server.FleetFileUpdatableFields", - "text": "FleetFileUpdatableFields" - }, - ">) => Promise<", - { - "pluginId": "fleet", - "scope": "server", - "docId": "kibFleetPluginApi", - "section": "def-server.FleetFile", - "text": "FleetFile" - }, - ">" - ], + "label": "actionId", + "description": [], "path": "x-pack/plugins/fleet/server/services/files/types.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.update.$1", - "type": "string", - "tags": [], - "label": "fileId", - "description": [], - "signature": [ - "string" - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.update.$2", - "type": "Object", - "tags": [], - "label": "updates", - "description": [], - "signature": [ - "Partial<", - { - "pluginId": "fleet", - "scope": "server", - "docId": "kibFleetPluginApi", - "section": "def-server.FleetFileUpdatableFields", - "text": "FleetFileUpdatableFields" - }, - ">" - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-server.FleetFromHostFileClientInterface", + "type": "Interface", + "tags": [], + "label": "FleetFromHostFileClientInterface", + "description": [ + "\nInterface for files that were created by a host and consumed in kibana" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.doesFileHaveData", + "id": "def-server.FleetFromHostFileClientInterface.doesFileHaveData", "type": "Function", "tags": [], "label": "doesFileHaveData", @@ -5865,7 +5728,7 @@ "children": [ { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.doesFileHaveData.$1", + "id": "def-server.FleetFromHostFileClientInterface.doesFileHaveData.$1", "type": "string", "tags": [], "label": "fileId", @@ -5883,7 +5746,7 @@ }, { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.download", + "id": "def-server.FleetFromHostFileClientInterface.download", "type": "Function", "tags": [], "label": "download", @@ -5901,7 +5764,7 @@ "children": [ { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.download.$1", + "id": "def-server.FleetFromHostFileClientInterface.download.$1", "type": "string", "tags": [], "label": "fileId", @@ -5919,7 +5782,7 @@ }, { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.get", + "id": "def-server.FleetFromHostFileClientInterface.get", "type": "Function", "tags": [], "label": "get", @@ -5943,7 +5806,7 @@ "children": [ { "parentPluginId": "fleet", - "id": "def-server.FleetFileClientInterface.get.$1", + "id": "def-server.FleetFromHostFileClientInterface.get.$1", "type": "string", "tags": [], "label": "fileId", @@ -5962,45 +5825,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileUpdatableFields", - "type": "Interface", - "tags": [], - "label": "FleetFileUpdatableFields", - "description": [], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileUpdatableFields.agents", - "type": "Array", - "tags": [], - "label": "agents", - "description": [], - "signature": [ - "string[]" - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileUpdatableFields.actionId", - "type": "string", - "tags": [], - "label": "actionId", - "description": [], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "fleet", "id": "def-server.FleetSetupDeps", @@ -6180,6 +6004,217 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface", + "type": "Interface", + "tags": [], + "label": "FleetToHostFileClientInterface", + "description": [ + "\nInterface for files created via kibana to be delivered to a hosts" + ], + "signature": [ + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.FleetToHostFileClientInterface", + "text": "FleetToHostFileClientInterface" + }, + " extends ", + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.FleetFromHostFileClientInterface", + "text": "FleetFromHostFileClientInterface" + } + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [ + "Creates a new file" + ], + "signature": [ + "(fileStream: ", + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.HapiReadableStream", + "text": "HapiReadableStream" + }, + ", agentIds: string[]) => Promise<", + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.FleetFile", + "text": "FleetFile" + }, + ">" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.create.$1", + "type": "Object", + "tags": [], + "label": "fileStream", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.HapiReadableStream", + "text": "HapiReadableStream" + } + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.create.$2", + "type": "Array", + "tags": [], + "label": "agentIds", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.delete", + "type": "Function", + "tags": [], + "label": "delete", + "description": [ + "Deletes a file" + ], + "signature": [ + "(fileId: string) => Promise" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.delete.$1", + "type": "string", + "tags": [], + "label": "fileId", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.update", + "type": "Function", + "tags": [], + "label": "update", + "description": [ + "Updates metadata for the file" + ], + "signature": [ + "(fileId: string, updates: Partial<", + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.FleetFileUpdatableFields", + "text": "FleetFileUpdatableFields" + }, + ">) => Promise<", + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.FleetFile", + "text": "FleetFile" + }, + ">" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.update.$1", + "type": "string", + "tags": [], + "label": "fileId", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.FleetToHostFileClientInterface.update.$2", + "type": "Object", + "tags": [], + "label": "updates", + "description": [], + "signature": [ + "Partial<", + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.FleetFileUpdatableFields", + "text": "FleetFileUpdatableFields" + }, + ">" + ], + "path": "x-pack/plugins/fleet/server/services/files/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-server.HapiReadableStream", @@ -9693,23 +9728,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetFileTransferDirection", - "type": "Type", - "tags": [], - "label": "FleetFileTransferDirection", - "description": [ - "\nThe type of file.\nUse `from-host` when interacting with files that were sent to ES from the\nhost (via Fleet-Server)\nUse `to-host` when interacting with files that are being sent to the host\n(via fleet-server)" - ], - "signature": [ - "\"from-host\" | \"to-host\"" - ], - "path": "x-pack/plugins/fleet/server/services/files/types.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "fleet", "id": "def-server.ListArtifactsProps", @@ -16856,87 +16874,34 @@ { "parentPluginId": "fleet", "id": "def-server.FleetStartContract.createFilesClient", - "type": "Function", + "type": "Object", "tags": [], "label": "createFilesClient", "description": [ "\nCreate a Fleet Files client instance" ], "signature": [ - "(packageName: string, type: ", + "{ readonly toHost: (packageName: string, maxSizeBytes?: number | undefined) => ", { "pluginId": "fleet", "scope": "server", "docId": "kibFleetPluginApi", - "section": "def-server.FleetFileTransferDirection", - "text": "FleetFileTransferDirection" + "section": "def-server.FleetToHostFileClientInterface", + "text": "FleetToHostFileClientInterface" }, - ", maxSizeBytes?: number | undefined) => ", + "; readonly fromHost: (packageName: string) => ", { "pluginId": "fleet", "scope": "server", "docId": "kibFleetPluginApi", - "section": "def-server.FleetFileClientInterface", - "text": "FleetFileClientInterface" - } + "section": "def-server.FleetFromHostFileClientInterface", + "text": "FleetFromHostFileClientInterface" + }, + "; }" ], "path": "x-pack/plugins/fleet/server/plugin.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "fleet", - "id": "def-server.FleetStartContract.createFilesClient.$1", - "type": "string", - "tags": [], - "label": "packageName", - "description": [], - "signature": [ - "string" - ], - "path": "x-pack/plugins/fleet/server/plugin.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetStartContract.createFilesClient.$2", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - { - "pluginId": "fleet", - "scope": "server", - "docId": "kibFleetPluginApi", - "section": "def-server.FleetFileTransferDirection", - "text": "FleetFileTransferDirection" - } - ], - "path": "x-pack/plugins/fleet/server/plugin.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "fleet", - "id": "def-server.FleetStartContract.createFilesClient.$3", - "type": "number", - "tags": [], - "label": "maxSizeBytes", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/fleet/server/plugin.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - } - ], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "fleet", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index a0145145e3116..d40387e32c9c3 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1159 | 3 | 1045 | 31 | +| 1156 | 3 | 1041 | 31 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index cfb1657ba770a..fab9789b92148 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-05-31 +date: 2023-06-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 582f9227fad05..496e74b269fe0 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-05-31 +date: 2023-06-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 662763a745f79..97a9cac9052c6 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-05-31 +date: 2023-06-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 66ec85c84e2e1..66ed327882d17 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-05-31 +date: 2023-06-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 64f1138e6625b..4fe2debbb803b 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-05-31 +date: 2023-06-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 81cb4a5fd1bb0..672eaba60e088 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-05-31 +date: 2023-06-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 efd96d2780caa..6affd25e1bbd7 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-05-31 +date: 2023-06-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 b1f4ebb32401d..2b8dfa1d4f9b2 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-05-31 +date: 2023-06-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 1664afa65c273..e77140d7c1883 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-05-31 +date: 2023-06-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 dc2370ff07f94..662f1d8a5498a 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-05-31 +date: 2023-06-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 d3e07f917a73b..b7f2f8f13b291 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-05-31 +date: 2023-06-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 ef88a26eb39a6..8a736698418b9 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-05-31 +date: 2023-06-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 e638d5a6d4945..f7eaa3c879524 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-05-31 +date: 2023-06-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 e14836eb4eb1d..636525d190840 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-05-31 +date: 2023-06-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 8bc529e28909f..932be22347087 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-05-31 +date: 2023-06-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 03fcc6ba60fca..28eb78f9f838f 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-05-31 +date: 2023-06-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 2747b9bfc449f..a6ea1a9c31f49 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-05-31 +date: 2023-06-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 59e82dbb77c4d..c945323ee79ee 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-05-31 +date: 2023-06-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 a2d11a3c60c26..dd0df026a79fb 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-05-31 +date: 2023-06-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 07f9100a2dfbf..ab588450d57b6 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-05-31 +date: 2023-06-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 c0c69045c6ed7..ed7abadaa20d5 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-05-31 +date: 2023-06-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 289a0c8a3baa4..c827644f398ab 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-05-31 +date: 2023-06-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 14f745442a964..efb093cb139fc 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-05-31 +date: 2023-06-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 afa1c7291808b..cd5edff4adcbd 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-05-31 +date: 2023-06-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 c5f3c6ccf95c0..75c8193aa882e 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-05-31 +date: 2023-06-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 d617e5f3e634f..91fda4808759e 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-05-31 +date: 2023-06-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 8c0bb35f06d49..cd3b1d5f54eb5 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-05-31 +date: 2023-06-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 0bd3908a6c8d0..72b214e035015 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-05-31 +date: 2023-06-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.mdx b/api_docs/kbn_cell_actions.mdx index 03c7603269f72..35466040e489b 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-05-31 +date: 2023-06-01 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 fb5bc0cacfc97..ec1ab3be29090 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-05-31 +date: 2023-06-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 505bbb5398f9c..3ab0c5bf152fa 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-05-31 +date: 2023-06-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 92bbe0ba75450..2f8d726b9895c 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-05-31 +date: 2023-06-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 8edc02c21fdc4..922c49943a140 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-05-31 +date: 2023-06-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 ea0c6d91b049d..be200be94db16 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-05-31 +date: 2023-06-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 77efc9cff6dee..df18358ff0e1b 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-05-31 +date: 2023-06-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 a777374f10150..7606112ffb6e8 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-05-31 +date: 2023-06-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 a5d74aff02abf..dbd076ebae084 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-05-31 +date: 2023-06-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 9a989221b0768..aea913413ce2d 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-05-31 +date: 2023-06-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 6e98c7478fc4e..ed859428b4ea8 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-05-31 +date: 2023-06-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 eb88f5b8ca5ad..8331890c64e91 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-05-31 +date: 2023-06-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 341b9e64bdf44..a6f5930f3b830 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-05-31 +date: 2023-06-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 6d7177e7d6a39..f566a508067a5 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-05-31 +date: 2023-06-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_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index 6ae5f97cb1129..3f83fede0192c 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2023-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index d2b3e74b8405f..d86f551d1615a 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-05-31 +date: 2023-06-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 9e38ea300e572..db0f558c86647 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-05-31 +date: 2023-06-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 ccdae74281e8f..66c21c625a472 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-05-31 +date: 2023-06-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 689084b276d52..e82bbea0bf1e5 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-05-31 +date: 2023-06-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 8785b9ab4008d..a0cf1fb33ce18 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-05-31 +date: 2023-06-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 11e42ff5ef8bb..cad29109bdf19 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-05-31 +date: 2023-06-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 84e504a1bf40f..db87564751444 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-05-31 +date: 2023-06-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 7e43edc35245e..1296ae67cb8ff 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-05-31 +date: 2023-06-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 2147aef4999e2..3aba13cc9879e 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-05-31 +date: 2023-06-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 9e88a03661f74..1ce53849273d3 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-05-31 +date: 2023-06-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 e04be488d3ec9..f7d3f0e3d02e5 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-05-31 +date: 2023-06-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 5bd1760291afe..f77d0a4d1742b 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-05-31 +date: 2023-06-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 de92a1a20aca9..bad4f21c4195a 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-05-31 +date: 2023-06-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 48e2537fb6035..3faacb9708068 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-05-31 +date: 2023-06-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 91d41ec5b9065..c3468ec8c4428 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-05-31 +date: 2023-06-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 9d162018d9a1c..0e34bf7e9847c 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-05-31 +date: 2023-06-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 1cee5b59f7ab1..3b9d0860153d0 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-05-31 +date: 2023-06-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 ae3ab56fdb603..38f6c2a757400 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-05-31 +date: 2023-06-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 6aa2224da3f39..58047cd561721 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-05-31 +date: 2023-06-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 73d49e91741b4..6b13090f6b92d 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-05-31 +date: 2023-06-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 5e3e79f76da0d..45e30348be140 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-05-31 +date: 2023-06-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 7050b185df3c0..977116cad2411 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-05-31 +date: 2023-06-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 eaacdae95bf21..9575be30fdcad 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-05-31 +date: 2023-06-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 e0225e5c2997a..34bdc4b3a5ba7 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-05-31 +date: 2023-06-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 893f2d833eb3b..88fb8bfa6882d 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-05-31 +date: 2023-06-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 f937ff97048d9..31353bc86c7b4 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-05-31 +date: 2023-06-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 98eeb60e5eee2..9de3f9476db38 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-05-31 +date: 2023-06-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 f4930879133ea..f881d78df8a97 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-05-31 +date: 2023-06-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 cdf6750b8066b..332d61379a49a 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-05-31 +date: 2023-06-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 784e81307fc63..cb94dcc08c931 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-05-31 +date: 2023-06-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 f495b5bbcd5d8..e475151f13e7e 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-05-31 +date: 2023-06-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 713868958d001..f104859ff7f0e 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-05-31 +date: 2023-06-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 96a40c482a014..ee7ca23f3f620 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-05-31 +date: 2023-06-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 cffba16e4c237..7458eae99e416 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-05-31 +date: 2023-06-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 fffbbfc73eaa8..2464e6ec84cb6 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-05-31 +date: 2023-06-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 59c4a74f436ee..2a786bf8821f6 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-05-31 +date: 2023-06-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 4f5f25d635fcf..1c82c73752f65 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-05-31 +date: 2023-06-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 2e6f1129fdb1a..19b3cfd6b7be5 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-05-31 +date: 2023-06-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 b53622059e5b9..feb36233f5cc0 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-05-31 +date: 2023-06-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 674e8db4e4392..aaaf86a73e7ee 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-05-31 +date: 2023-06-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 dfaeb0604b503..be45fa19dc5d4 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-05-31 +date: 2023-06-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 bbbcdcf55ff21..1d43e6bf88f91 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-05-31 +date: 2023-06-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 6e4c08fbf4095..df0436439d7fc 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-05-31 +date: 2023-06-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 1db59a4fd60e6..7d93498130604 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-05-31 +date: 2023-06-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 20b7d056c1e81..fd7c611291537 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-05-31 +date: 2023-06-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 1600b2ab4ae52..61629aad5543b 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-05-31 +date: 2023-06-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 e758fb68ab1cd..ee381b4836809 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-05-31 +date: 2023-06-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 d45dbdad0e3d8..dec8dd2fe94c8 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-05-31 +date: 2023-06-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 8a0688e6b4d9f..f4432d68cd740 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-05-31 +date: 2023-06-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 1ada180470d39..10891036faeef 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-05-31 +date: 2023-06-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 ef5a073c7e130..63296bb99b0df 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-05-31 +date: 2023-06-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 bbc958457290d..3c063be98134f 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-05-31 +date: 2023-06-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 1607f8f411877..9b410d3eda1ce 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-05-31 +date: 2023-06-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 9c0fc35cb6cde..ba46f9c075294 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-05-31 +date: 2023-06-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 580e54e6a5fa5..d8c78a215e7f7 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-05-31 +date: 2023-06-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 87f7d7da57b76..2284774b1a9b7 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-05-31 +date: 2023-06-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 a0f12b39fe26c..5a675da1d194b 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-05-31 +date: 2023-06-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 202c5b957d558..b29549224bfd8 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-05-31 +date: 2023-06-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 5e02cace2ca8f..50e9006011751 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-05-31 +date: 2023-06-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 6d4831672e582..44501c13f40ee 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-05-31 +date: 2023-06-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 f74d2da762df7..9158d822ec6d0 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-05-31 +date: 2023-06-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 80a888702ada4..0efc141d07071 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-05-31 +date: 2023-06-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 6e060eb5faf86..fdeaf3e0153bc 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-05-31 +date: 2023-06-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 0b14e6d69e83d..8e3b14ca0ac3c 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-05-31 +date: 2023-06-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 75d8cabb477e9..9fd84220a62ea 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-05-31 +date: 2023-06-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 366a2dc0fed9b..de4004e5b05ed 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-05-31 +date: 2023-06-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 4b745f82eecc0..84281085c103f 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-05-31 +date: 2023-06-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 c097bb4851248..fc8ea17f415ac 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-05-31 +date: 2023-06-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 c93039ca95745..8b62532b75f94 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-05-31 +date: 2023-06-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 4946365084706..dbb7b1fe39a34 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-05-31 +date: 2023-06-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.mdx b/api_docs/kbn_core_http_server.mdx index cc326ac8ff9da..2761083272637 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-05-31 +date: 2023-06-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 6f8ee5eb282eb..e126d44e6bffb 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-05-31 +date: 2023-06-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 deef84b1a1071..8244bca24d416 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-05-31 +date: 2023-06-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 5e060b7f75aef..8582ebec20373 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-05-31 +date: 2023-06-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 68196aec9a6bc..f541e23984e3b 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-05-31 +date: 2023-06-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 b610053147e05..e3bfea30bdd99 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-05-31 +date: 2023-06-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 318637fe23cc0..9154f10d0d725 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-05-31 +date: 2023-06-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 4b1a275d68152..83d38719f4a5b 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-05-31 +date: 2023-06-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 1ab8395ccb37f..40b74a45ca0be 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-05-31 +date: 2023-06-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 d07618c603b1c..8d6ec5aee54bd 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-05-31 +date: 2023-06-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 8f1a06f020703..86072d3b694ec 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-05-31 +date: 2023-06-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.devdocs.json b/api_docs/kbn_core_lifecycle_browser.devdocs.json index c646c8e5f12d2..3819468b4cc23 100644 --- a/api_docs/kbn_core_lifecycle_browser.devdocs.json +++ b/api_docs/kbn_core_lifecycle_browser.devdocs.json @@ -601,6 +601,10 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_actions/index.ts" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, { "plugin": "lens", "path": "x-pack/plugins/lens/public/datasources/form_based/form_based.tsx" @@ -689,6 +693,26 @@ "plugin": "transform", "path": "x-pack/plugins/transform/public/app/mount_management_section.ts" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/main/services/discover_saved_search_container.test.ts" @@ -716,10 +740,6 @@ { "plugin": "ml", "path": "x-pack/plugins/ml/public/application/services/dashboard_service.ts" - }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" } ] }, diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 7a3ed99281a45..65d3f6fa66703 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-05-31 +date: 2023-06-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 e698a626cbcda..fbbb54756d2cc 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-05-31 +date: 2023-06-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 314bdee3de3c3..9a2df400aa740 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-05-31 +date: 2023-06-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 7ee5d1dc2a736..913ea89fa9750 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-05-31 +date: 2023-06-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 3b228cbdc2405..dbf17b67ae503 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-05-31 +date: 2023-06-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 914b52fbaff12..b4cdc4591c542 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-05-31 +date: 2023-06-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 fe83df20a14fd..68415bd802062 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-05-31 +date: 2023-06-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 1d8b12192a0ec..27f29856f91cf 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-05-31 +date: 2023-06-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 6e39d3bc42a17..0e2298f4ba7b8 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-05-31 +date: 2023-06-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 15fbbc35f4a6c..1e6089b520d51 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-05-31 +date: 2023-06-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 96456536d239a..a0873931c620a 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-05-31 +date: 2023-06-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 fc15c7f0cd4f0..72c92c6aacf0c 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-05-31 +date: 2023-06-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 55dd8ff3a8ed3..4ea911c672908 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-05-31 +date: 2023-06-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 c48d3143a4277..be358f92b7b69 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-05-31 +date: 2023-06-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 c666a176ebd4f..224c44ace8144 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-05-31 +date: 2023-06-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 5f190935f4445..69e8481b0d4f2 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-05-31 +date: 2023-06-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 d027c8e586bfb..390788ad6b884 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-05-31 +date: 2023-06-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 5c5056a2f3456..d79d1fa077c2c 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-05-31 +date: 2023-06-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 1d095bf33c1a8..0e3fe9d773ff4 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-05-31 +date: 2023-06-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 3fc6af1e2481e..30c9725758abb 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-05-31 +date: 2023-06-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 f4c8a342d2ce8..746b48ef3e0d7 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-05-31 +date: 2023-06-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 391eabd266ac0..59a51ce4f23cd 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-05-31 +date: 2023-06-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 0d8ffbfd855e8..62f5f6eb60978 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-05-31 +date: 2023-06-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 e88ead9d207e0..a7e2577c3e796 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-05-31 +date: 2023-06-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 a34f13fea4681..4df46b5dec936 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-05-31 +date: 2023-06-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 a63a9c6d18e3f..d02b7fb478e41 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-05-31 +date: 2023-06-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 f59ec7124b3d0..0431be1c94082 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-05-31 +date: 2023-06-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 008f2b342784a..ee44c8faed7cd 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-05-31 +date: 2023-06-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 4342943b4ea53..1f684a4ff6e7c 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-05-31 +date: 2023-06-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 e2a514cc1069b..2d7c6afcfef32 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-05-31 +date: 2023-06-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 c1147733ea182..32d9706c91332 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-05-31 +date: 2023-06-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 4bdb10d831c36..50f18f1cfc312 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-05-31 +date: 2023-06-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 d088d01bb1282..e41ad8c1254d3 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-05-31 +date: 2023-06-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 a4e6128308fea..b108364d4e170 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-05-31 +date: 2023-06-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.devdocs.json b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json index af282c53fbcb2..68134fb30d856 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json @@ -1058,6 +1058,14 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/plugin.tsx" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, { "plugin": "lens", "path": "x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx" @@ -1262,6 +1270,18 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_actions/clone_panel_action.tsx" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/saved_object/saved_object.test.ts" @@ -1465,6 +1485,10 @@ "plugin": "home", "path": "src/plugins/home/public/application/components/home_app.js" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, { "plugin": "@kbn/core-saved-objects-browser-internal", "path": "packages/core/saved-objects/core-saved-objects-browser-internal/src/saved_objects_client.ts" @@ -1847,6 +1871,10 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_actions/clone_panel_action.tsx" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" @@ -1859,10 +1887,6 @@ "plugin": "ml", "path": "x-pack/plugins/ml/public/application/services/dashboard_service.ts" }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" - }, { "plugin": "dashboardEnhanced", "path": "x-pack/plugins/dashboard_enhanced/public/services/drilldowns/abstract_dashboard_drilldown/components/collect_config_container.tsx" @@ -1979,6 +2003,10 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_actions/clone_panel_action.tsx" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/public/application/util/index_utils.ts" @@ -1991,10 +2019,6 @@ "plugin": "ml", "path": "x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts" }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" - }, { "plugin": "dashboardEnhanced", "path": "x-pack/plugins/dashboard_enhanced/public/services/drilldowns/abstract_dashboard_drilldown/components/collect_config_container.tsx" @@ -2003,6 +2027,10 @@ "plugin": "monitoring", "path": "x-pack/plugins/monitoring/public/application/pages/elasticsearch/ingest_pipeline_modal.tsx" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/saved_object/saved_object.test.ts" @@ -2506,6 +2534,14 @@ "plugin": "savedSearch", "path": "src/plugins/saved_search/public/services/saved_searches/save_saved_searches.ts" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/saved_object/saved_object.test.ts" @@ -3395,18 +3431,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/types.ts" }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" - }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" - }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" - }, { "plugin": "dashboardEnhanced", "path": "x-pack/plugins/dashboard_enhanced/public/services/drilldowns/abstract_dashboard_drilldown/components/collect_config_container.tsx" @@ -3455,6 +3479,14 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/hooks/types.ts" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.test.ts" + }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/saved_object/saved_object.test.ts" @@ -4056,14 +4088,6 @@ { "plugin": "@kbn/core", "path": "src/core/public/index.ts" - }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" - }, - { - "plugin": "cloudSecurityPosture", - "path": "x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts" } ], "initialIsOpen": false diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 188e0506b5fa5..8a88ac3b280e5 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-05-31 +date: 2023-06-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 b8204ea6048de..5ed793b60328b 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-05-31 +date: 2023-06-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 5f65f2c1251b4..fec9a1cfb86a5 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-05-31 +date: 2023-06-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 9962418df92dc..8b31698cf3e3f 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-05-31 +date: 2023-06-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 07c5b384c20dc..9a7dd2f2352a3 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-05-31 +date: 2023-06-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 97f0e8156d1a5..6ad95e68f0795 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-05-31 +date: 2023-06-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 fc0d6bf405ed7..61948cdfe260b 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-05-31 +date: 2023-06-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 c64bb83eb520e..ecbb14a5e2bc8 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-05-31 +date: 2023-06-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.devdocs.json b/api_docs/kbn_core_saved_objects_common.devdocs.json index 5272b05c60116..339253c958d8e 100644 --- a/api_docs/kbn_core_saved_objects_common.devdocs.json +++ b/api_docs/kbn_core_saved_objects_common.devdocs.json @@ -2114,6 +2114,14 @@ "plugin": "visualizations", "path": "src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx" }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, + { + "plugin": "eventAnnotation", + "path": "src/plugins/event_annotation/public/event_annotation_service/service.tsx" + }, { "plugin": "savedObjectsTagging", "path": "x-pack/plugins/saved_objects_tagging/public/ui_api/get_table_column_definition.tsx" @@ -2158,6 +2166,10 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts" }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts" + }, { "plugin": "lens", "path": "x-pack/plugins/lens/public/state_management/selectors.ts" @@ -2254,6 +2266,14 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/types.ts" }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/types.ts" + }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/types.ts" + }, { "plugin": "lens", "path": "x-pack/plugins/lens/public/visualizations/xy/state_helpers.ts" @@ -2266,6 +2286,14 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/visualizations/xy/state_helpers.ts" }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/visualizations/xy/visualization.tsx" + }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/visualizations/xy/visualization.tsx" + }, { "plugin": "lens", "path": "x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx" diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 8b4d9c4cdabbd..802ef3677fce3 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-05-31 +date: 2023-06-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 ce6c8b47e011d..293cbfc569cde 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-05-31 +date: 2023-06-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 4aeb0c43fa25b..f2051393e4075 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-05-31 +date: 2023-06-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.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 93c14d179e85e..df651dcadb222 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-05-31 +date: 2023-06-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'; 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 0469e36161a75..f56f6f2fb5019 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-05-31 +date: 2023-06-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 3888209c39ae7..5f0fdca9aa1fb 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-05-31 +date: 2023-06-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 dc27ce90f1812..ed7a347cbdd78 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-05-31 +date: 2023-06-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 8b7cbffa6f671..18e054d52eb69 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-05-31 +date: 2023-06-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 a812a3cfe5735..fc4537051b844 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-05-31 +date: 2023-06-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 16c68b89dbafc..0b6f6f650f704 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-05-31 +date: 2023-06-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 8dd1e9718be94..e5264f618c211 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-05-31 +date: 2023-06-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 bd86cc6128765..ff76a7616e6f3 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-05-31 +date: 2023-06-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 8c9f58d0e5225..ccf5751ab1653 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-05-31 +date: 2023-06-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 d1de68b85b0bd..a2d8e41cc2179 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-05-31 +date: 2023-06-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 02eb38627bcc1..1b7d7d8780689 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-05-31 +date: 2023-06-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 2a59c82b7df30..869dd2773bc1c 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-05-31 +date: 2023-06-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 08b07cdafe9a6..6d3f1cbfd8100 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-05-31 +date: 2023-06-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 67277796c65be..28dfca1812eb0 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-05-31 +date: 2023-06-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 59b4c6a8ed4e4..6efcedab70d5a 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-05-31 +date: 2023-06-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 06307e57b120b..0a6095819894e 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-05-31 +date: 2023-06-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 0c68289f670ac..0d8323e1ee5c4 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-05-31 +date: 2023-06-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 579262b31994c..c3500f60b3af1 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-05-31 +date: 2023-06-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 aba1201d28724..277b1fbb604a5 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-05-31 +date: 2023-06-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 45e7dec31c982..34c79010aeba5 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-05-31 +date: 2023-06-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 e1ab85a3a5af5..4728b82e2af27 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-05-31 +date: 2023-06-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 7fd2879c73e8f..57ccabbd40dc5 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-05-31 +date: 2023-06-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 95461704a399c..c1672924d0a64 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-05-31 +date: 2023-06-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 b818760780d0a..2d49b235c16ac 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-05-31 +date: 2023-06-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 e6089172dc336..61357d16808bc 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-05-31 +date: 2023-06-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 d636a54a30ae3..58f737a96cb9d 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-05-31 +date: 2023-06-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 7eb06f6872dfe..ba1250109fa2c 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-05-31 +date: 2023-06-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 710f655101851..8114a5ba55f8b 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-05-31 +date: 2023-06-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 03792dd606d4f..07637bd523204 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-05-31 +date: 2023-06-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 5a6dbaa2262b7..53b70f3d12f3d 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-05-31 +date: 2023-06-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 709753c7fe2d9..340b5a01a40e4 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-05-31 +date: 2023-06-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 f6ae8808ca7aa..0f0054321e10c 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-05-31 +date: 2023-06-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 b662bc0582370..a12af44d6381c 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-05-31 +date: 2023-06-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 79b25286e64cf..f13782996adcc 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 3e0036ec3d41d..76fa08971f884 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 2f9c832dbc079..9b0432b22fd3a 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-05-31 +date: 2023-06-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 e8c4db2feab55..be09644b5558a 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-05-31 +date: 2023-06-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 42b1848f467c3..74f19816542f6 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-05-31 +date: 2023-06-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 6c3b2c1d67499..63ef509144f31 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-05-31 +date: 2023-06-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 f4dc34aaa31e1..682635e56f191 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-05-31 +date: 2023-06-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 8204d6e763028..a1d7f4520f11c 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-05-31 +date: 2023-06-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 114f9e9deb6bf..823543d775d2c 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-05-31 +date: 2023-06-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 8e622d8477495..4d20d09c03afe 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-05-31 +date: 2023-06-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 c5ccd45ecf66f..5e917ccb1191b 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-05-31 +date: 2023-06-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 316f4015661f1..a78973975c4a6 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-05-31 +date: 2023-06-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_es.mdx b/api_docs/kbn_es.mdx index 1887fd1229962..805412ff857ea 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-05-31 +date: 2023-06-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 a26489daefeea..e8c6c70b4a413 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-05-31 +date: 2023-06-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 0133b56449db6..041ed73489cef 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-05-31 +date: 2023-06-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 74590c93da78d..dcc25f727ac70 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-05-31 +date: 2023-06-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 95af709814800..8bbca19764e0a 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-05-31 +date: 2023-06-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 daaac9768e06b..2d990aaf6c986 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-05-31 +date: 2023-06-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 bb29018d8b7fc..07ead1b866a57 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-05-31 +date: 2023-06-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 63cd8b1c156b2..cf98bb5cee684 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-05-31 +date: 2023-06-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 a51e6205b7244..13ff67934e975 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-05-31 +date: 2023-06-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 a680757911d61..5ac731a90c4b7 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-05-31 +date: 2023-06-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 5790117e32b58..455c012dd6495 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 3c5f84ecf45dd..1881ca1618bb6 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-05-31 +date: 2023-06-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 2368507a03b96..cc0be4de93844 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-05-31 +date: 2023-06-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 caf7283c4e54a..56ae1c2eb40d9 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-05-31 +date: 2023-06-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 0a5106fb35729..6b54920f26f84 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-05-31 +date: 2023-06-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 313089a3f7509..4f5719e64171b 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-05-31 +date: 2023-06-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 5ab6a7ad1bde4..e423ec26ef194 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-05-31 +date: 2023-06-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 3eee775b4d1cb..024d4c5c5da41 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-05-31 +date: 2023-06-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 9f45beb84521c..0050bb955ee56 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-05-31 +date: 2023-06-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 2ca9b6bb0efd8..4014df4502d46 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-05-31 +date: 2023-06-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 070751afc0d14..e53e73cf7fc00 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-05-31 +date: 2023-06-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 e6e090bc938ab..baadf930e2e3c 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-05-31 +date: 2023-06-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 17219f82f3300..6e28c7e56641d 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-05-31 +date: 2023-06-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 fd4a63c8eee99..adc05c830281c 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.devdocs.json b/api_docs/kbn_io_ts_utils.devdocs.json index 40cd0884ecb9d..c52cf0c809d50 100644 --- a/api_docs/kbn_io_ts_utils.devdocs.json +++ b/api_docs/kbn_io_ts_utils.devdocs.json @@ -200,6 +200,66 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/io-ts-utils", + "id": "def-common.inRangeFromStringRt", + "type": "Function", + "tags": [], + "label": "inRangeFromStringRt", + "description": [], + "signature": [ + "(start: number, end: number) => ", + "Type", + "<", + "Branded", + ", unknown, unknown>" + ], + "path": "packages/kbn-io-ts-utils/src/in_range_rt/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/io-ts-utils", + "id": "def-common.inRangeFromStringRt.$1", + "type": "number", + "tags": [], + "label": "start", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-io-ts-utils/src/in_range_rt/index.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/io-ts-utils", + "id": "def-common.inRangeFromStringRt.$2", + "type": "number", + "tags": [], + "label": "end", + "description": [], + "signature": [ + "number" + ], + "path": "packages/kbn-io-ts-utils/src/in_range_rt/index.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/io-ts-utils", "id": "def-common.inRangeRt", @@ -678,6 +738,22 @@ } ], "objects": [ + { + "parentPluginId": "@kbn/io-ts-utils", + "id": "def-common.datemathStringRt", + "type": "Object", + "tags": [], + "label": "datemathStringRt", + "description": [], + "signature": [ + "Type", + "" + ], + "path": "packages/kbn-io-ts-utils/src/datemath_string_rt/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/io-ts-utils", "id": "def-common.dateRt", diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 3013e449e8e21..e70292bc14f72 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) for ques | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 39 | 0 | 39 | 4 | +| 43 | 0 | 43 | 4 | ## Common diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 31c2d743eac27..8f42bcf6fb0ea 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-05-31 +date: 2023-06-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 ba4ee1711c2e5..150b143152e0c 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-05-31 +date: 2023-06-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 5c06fef2393ee..f2d34ded1596e 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-05-31 +date: 2023-06-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 9a52f5c6ca96e..64190bbbd2a86 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-05-31 +date: 2023-06-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 695dea35558cb..0cd4884ca440d 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-05-31 +date: 2023-06-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 c955cbb8c5826..042616e0a966b 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-05-31 +date: 2023-06-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 2346639c7e18b..11e71c17d8d2c 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-05-31 +date: 2023-06-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 fc46ff40bbd13..f30d51da33efe 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-05-31 +date: 2023-06-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_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index d823f94f64c4b..8211f13bed709 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-05-31 +date: 2023-06-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 fcde56fa46360..1b3d029a8da8b 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-05-31 +date: 2023-06-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 81e3912fcee35..06e12e1182856 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-05-31 +date: 2023-06-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 92ddc04d05bf1..a59df4f609518 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-05-31 +date: 2023-06-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.devdocs.json b/api_docs/kbn_ml_data_frame_analytics_utils.devdocs.json new file mode 100644 index 0000000000000..e256f334515c9 --- /dev/null +++ b/api_docs/kbn_ml_data_frame_analytics_utils.devdocs.json @@ -0,0 +1,3080 @@ +{ + "id": "@kbn/ml-data-frame-analytics-utils", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getAnalysisType", + "type": "Function", + "tags": [], + "label": "getAnalysisType", + "description": [ + "\nHelper function to get the analysis type of a DFA configuration\n" + ], + "signature": [ + "(analysis: ", + "MlDataframeAnalysisContainer", + ") => \"unknown\" | ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.DataFrameAnalysisConfigType", + "text": "DataFrameAnalysisConfigType" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getAnalysisType.$1", + "type": "Object", + "tags": [], + "label": "analysis", + "description": [ + "The analysis configuration" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getDefaultPredictionFieldName", + "type": "Function", + "tags": [], + "label": "getDefaultPredictionFieldName", + "description": [ + "\nHelper function to get the default prediction field name\n" + ], + "signature": [ + "(analysis: ", + "MlDataframeAnalysisContainer", + ") => string" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getDefaultPredictionFieldName.$1", + "type": "Object", + "tags": [], + "label": "analysis", + "description": [ + "The analysis configuration" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getDependentVar", + "type": "Function", + "tags": [], + "label": "getDependentVar", + "description": [ + "\nHelper function to get the dependent variable of a DFA configuration\n" + ], + "signature": [ + "(analysis: ", + "MlDataframeAnalysisContainer", + ") => string" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getDependentVar.$1", + "type": "Object", + "tags": [], + "label": "analysis", + "description": [ + "The analysis configuration" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getNumTopClasses", + "type": "Function", + "tags": [], + "label": "getNumTopClasses", + "description": [ + "\nGet the `num_top_classes` attribute of a DFA classification configuration\n" + ], + "signature": [ + "(analysis: ", + "MlDataframeAnalysisContainer", + ") => number | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/get_num_top_classes.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getNumTopClasses.$1", + "type": "Object", + "tags": [], + "label": "analysis", + "description": [ + "The analysis configuration" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/get_num_top_classes.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getNumTopFeatureImportanceValues", + "type": "Function", + "tags": [], + "label": "getNumTopFeatureImportanceValues", + "description": [ + "\nGet the `num_top_feature_importance_values` attribute of DFA regression and classification configurations\n" + ], + "signature": [ + "(analysis: ", + "MlDataframeAnalysisContainer", + ") => number | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/get_num_top_feature_importance_values.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getNumTopFeatureImportanceValues.$1", + "type": "Object", + "tags": [], + "label": "analysis", + "description": [ + "The analysis configuration" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/get_num_top_feature_importance_values.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getPredictionFieldName", + "type": "Function", + "tags": [], + "label": "getPredictionFieldName", + "description": [ + "\nHelper function to get the prediction field name of a DFA configuration\n" + ], + "signature": [ + "(analysis: ", + "MlDataframeAnalysisContainer", + ") => string | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getPredictionFieldName.$1", + "type": "Object", + "tags": [], + "label": "analysis", + "description": [ + "The analysis configuration" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getTrainingPercent", + "type": "Function", + "tags": [], + "label": "getTrainingPercent", + "description": [ + "\nHelper function to get the training percent of a DFA configuration\n" + ], + "signature": [ + "(analysis: ", + "MlDataframeAnalysisContainer", + ") => number | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.getTrainingPercent.$1", + "type": "Object", + "tags": [], + "label": "analysis", + "description": [ + "The analysis configuration" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isClassificationAnalysis", + "type": "Function", + "tags": [], + "label": "isClassificationAnalysis", + "description": [ + "\nType guard for DFA classification analysis configurations\n" + ], + "signature": [ + "(arg: unknown) => arg is ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.ClassificationAnalysis", + "text": "ClassificationAnalysis" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isClassificationAnalysis.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The config to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isClassificationFeatureImportanceBaseline", + "type": "Function", + "tags": [ + "export" + ], + "label": "isClassificationFeatureImportanceBaseline", + "description": [ + "\nType guard for classification feature importance baseline\n" + ], + "signature": [ + "(arg: unknown) => boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isClassificationFeatureImportanceBaseline.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The baseline to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isClassificationTotalFeatureImportance", + "type": "Function", + "tags": [ + "export" + ], + "label": "isClassificationTotalFeatureImportance", + "description": [ + "\nType guard for total feature importance\n" + ], + "signature": [ + "(arg: unknown) => boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isClassificationTotalFeatureImportance.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The feature importance to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isDataFrameAnalyticsConfigs", + "type": "Function", + "tags": [ + "export" + ], + "label": "isDataFrameAnalyticsConfigs", + "description": [ + "\nType guard for a DFA config\n" + ], + "signature": [ + "(arg: unknown) => boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isDataFrameAnalyticsConfigs.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The config to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isOutlierAnalysis", + "type": "Function", + "tags": [], + "label": "isOutlierAnalysis", + "description": [ + "\nType guard for DFA outlier analysis configurations\n" + ], + "signature": [ + "(arg: unknown) => arg is ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.OutlierAnalysis", + "text": "OutlierAnalysis" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isOutlierAnalysis.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The config to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isRegressionAnalysis", + "type": "Function", + "tags": [], + "label": "isRegressionAnalysis", + "description": [ + "\nType guard for DFA regression analysis configurations\n" + ], + "signature": [ + "(arg: unknown) => arg is ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.RegressionAnalysis", + "text": "RegressionAnalysis" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isRegressionAnalysis.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The config to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/analytics_utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isRegressionFeatureImportanceBaseline", + "type": "Function", + "tags": [ + "export" + ], + "label": "isRegressionFeatureImportanceBaseline", + "description": [ + "\nType guard for regression feature importance baseline\n" + ], + "signature": [ + "(arg: unknown) => boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isRegressionFeatureImportanceBaseline.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The baseline to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isRegressionTotalFeatureImportance", + "type": "Function", + "tags": [ + "export" + ], + "label": "isRegressionTotalFeatureImportance", + "description": [ + "\nType guard for regression total feature importance\n" + ], + "signature": [ + "(arg: unknown) => boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.isRegressionTotalFeatureImportance.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [ + "The feature importance to identify" + ], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.sortExplorationResultsFields", + "type": "Function", + "tags": [], + "label": "sortExplorationResultsFields", + "description": [ + "\nUsed to sort columns:\n- Anchor on the left ml.outlier_score, ml.is_training, , \n- string based columns are moved to the left\n- feature_influence/feature_importance fields get moved next to the corresponding field column\n- overall fields get sorted alphabetically\n" + ], + "signature": [ + "(a: string, b: string, jobConfig: ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.DataFrameAnalyticsConfig", + "text": "DataFrameAnalyticsConfig" + }, + ") => number" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.sortExplorationResultsFields.$1", + "type": "string", + "tags": [], + "label": "a", + "description": [ + "First field name to compare for sorting" + ], + "signature": [ + "string" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.sortExplorationResultsFields.$2", + "type": "string", + "tags": [], + "label": "b", + "description": [ + "Second field name to compare for sorting" + ], + "signature": [ + "string" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.sortExplorationResultsFields.$3", + "type": "Object", + "tags": [], + "label": "jobConfig", + "description": [ + "The DFA analysis config" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.DataFrameAnalyticsConfig", + "text": "DataFrameAnalyticsConfig" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapEdgeElement", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "AnalyticsMapEdgeElement", + "description": [ + "\nInterface for an edge element for the map view\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapEdgeElement.data", + "type": "Object", + "tags": [ + "type" + ], + "label": "data", + "description": [ + "\nInner data of the edge element" + ], + "signature": [ + "{ id: string; source: string; target: string; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapNodeElement", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "AnalyticsMapNodeElement", + "description": [ + "\nInterface for a node element for the map view\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapNodeElement.data", + "type": "Object", + "tags": [ + "type" + ], + "label": "data", + "description": [ + "\nInner data of the node element" + ], + "signature": [ + "{ id: string; label: string; type: string; analysisType?: string | undefined; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapReturnType", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "AnalyticsMapReturnType", + "description": [ + "\nInterface for DFA map return type\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapReturnType.elements", + "type": "Array", + "tags": [ + "type" + ], + "label": "elements", + "description": [ + "\nMap elements" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.MapElements", + "text": "MapElements" + }, + "[]" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapReturnType.details", + "type": "Object", + "tags": [ + "type" + ], + "label": "details", + "description": [ + "\nTransform, job or index details" + ], + "signature": [ + "{ [x: string]: any; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalyticsMapReturnType.error", + "type": "Any", + "tags": [ + "type" + ], + "label": "error", + "description": [ + "\nError" + ], + "signature": [ + "any" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassFeatureImportance", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "ClassFeatureImportance", + "description": [ + "\nES result class feature importance\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassFeatureImportance.class_name", + "type": "CompoundType", + "tags": [ + "type" + ], + "label": "class_name", + "description": [ + "\nThe class name" + ], + "signature": [ + "string | number | boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassFeatureImportance.importance", + "type": "number", + "tags": [ + "type" + ], + "label": "importance", + "description": [ + "\nThe importance" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassFeatureImportanceSummary", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "ClassFeatureImportanceSummary", + "description": [ + "\nES result for class feature importance summary\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassFeatureImportanceSummary.class_name", + "type": "CompoundType", + "tags": [ + "type" + ], + "label": "class_name", + "description": [ + "\nThe class name" + ], + "signature": [ + "string | number | boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassFeatureImportanceSummary.importance", + "type": "Object", + "tags": [ + "type" + ], + "label": "importance", + "description": [ + "\nThe importance" + ], + "signature": [ + "{ max: number; min: number; mean_magnitude: number; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationAnalysis", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "ClassificationAnalysis", + "description": [ + "\nInterface for classification job configuation\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationAnalysis.Unnamed", + "type": "IndexSignature", + "tags": [], + "label": "[key: string]: Classification", + "description": [ + "\nKey spec for interface" + ], + "signature": [ + "[key: string]: Classification" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationAnalysis.classification", + "type": "Object", + "tags": [ + "type" + ], + "label": "classification", + "description": [ + "\nOutlier detection options" + ], + "signature": [ + "Classification" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationEvaluateResponse", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "ClassificationEvaluateResponse", + "description": [ + "\nInterface for classification evaluate response\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationEvaluateResponse.classification", + "type": "Object", + "tags": [ + "type" + ], + "label": "classification", + "description": [ + "\nClassificatio evaluation" + ], + "signature": [ + "{ multiclass_confusion_matrix?: { confusion_matrix: ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.ConfusionMatrix", + "text": "ConfusionMatrix" + }, + "[]; } | undefined; recall?: { classes: EvalClass[]; avg_recall: number; } | undefined; accuracy?: { classes: EvalClass[]; overall_accuracy: number; } | undefined; auc_roc?: { curve?: ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.RocCurveItem", + "text": "RocCurveItem" + }, + "[] | undefined; value: number; } | undefined; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationFeatureImportanceBaseline", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "ClassificationFeatureImportanceBaseline", + "description": [ + "\nBaseline interface for ES result classification feature importance\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationFeatureImportanceBaseline.classes", + "type": "Array", + "tags": [ + "type" + ], + "label": "classes", + "description": [ + "\nClasses" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.FeatureImportanceClassBaseline", + "text": "FeatureImportanceClassBaseline" + }, + "[]" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationTotalFeatureImportance", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "ClassificationTotalFeatureImportance", + "description": [ + "\nES result classification total feature importance\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationTotalFeatureImportance.feature_name", + "type": "string", + "tags": [ + "type" + ], + "label": "feature_name", + "description": [ + "\nThe feature name" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ClassificationTotalFeatureImportance.classes", + "type": "Array", + "tags": [ + "type" + ], + "label": "classes", + "description": [ + "\nThe classes, array of ClassFeatureImportanceSummary" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.ClassFeatureImportanceSummary", + "text": "ClassFeatureImportanceSummary" + }, + "[]" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ConfusionMatrix", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "ConfusionMatrix", + "description": [ + "\nInterface for confusion matrix\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ConfusionMatrix.actual_class", + "type": "string", + "tags": [ + "type" + ], + "label": "actual_class", + "description": [ + "\nActual class" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ConfusionMatrix.actual_class_doc_count", + "type": "number", + "tags": [ + "type" + ], + "label": "actual_class_doc_count", + "description": [ + "\nActual class doc count" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ConfusionMatrix.predicted_classes", + "type": "Array", + "tags": [ + "type" + ], + "label": "predicted_classes", + "description": [ + "\nArray of predicted classes" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.PredictedClass", + "text": "PredictedClass" + }, + "[]" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ConfusionMatrix.other_predicted_class_doc_count", + "type": "number", + "tags": [ + "type" + ], + "label": "other_predicted_class_doc_count", + "description": [ + "\nDoc count of other predicted classes" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsConfig", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef", + "extends" + ], + "label": "DataFrameAnalyticsConfig", + "description": [ + "\nInterface for a DFA config with fix for estypes provided types\n" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.DataFrameAnalyticsConfig", + "text": "DataFrameAnalyticsConfig" + }, + " extends Omit<", + "MlDataframeAnalyticsSummary", + ", \"analyzed_fields\">" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsConfig.analyzed_fields", + "type": "Object", + "tags": [ + "type" + ], + "label": "analyzed_fields", + "description": [ + "\nOptional analyzed fields" + ], + "signature": [ + "MlDataframeAnalysisAnalyzedFields", + " | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsConfig._meta", + "type": "Object", + "tags": [ + "type" + ], + "label": "_meta", + "description": [ + "\nOptional meta data" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.DataFrameAnalyticsMeta", + "text": "DataFrameAnalyticsMeta" + }, + " | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsMeta", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "DataFrameAnalyticsMeta", + "description": [ + "\nMeta data for a DFA job\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsMeta.custom_urls", + "type": "Array", + "tags": [ + "type" + ], + "label": "custom_urls", + "description": [ + "\nOptional custom urls" + ], + "signature": [ + { + "pluginId": "@kbn/ml-anomaly-utils", + "scope": "common", + "docId": "kibKbnMlAnomalyUtilsPluginApi", + "section": "def-common.MlUrlConfig", + "text": "MlUrlConfig" + }, + "[] | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsMeta.Unnamed", + "type": "IndexSignature", + "tags": [], + "label": "[key: string]: any", + "description": [ + "\nKey spec for interface" + ], + "signature": [ + "[key: string]: any" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsStats", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef", + "extends" + ], + "label": "DataFrameAnalyticsStats", + "description": [ + "\nInterface for DFA stats\n" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.DataFrameAnalyticsStats", + "text": "DataFrameAnalyticsStats" + }, + " extends Omit<", + "MlDataframeAnalytics", + ", \"state\">" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsStats.failure_reason", + "type": "string", + "tags": [ + "type" + ], + "label": "failure_reason", + "description": [ + "\nOptional failure reason" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsStats.state", + "type": "CompoundType", + "tags": [ + "type" + ], + "label": "state", + "description": [ + "\nTask state" + ], + "signature": [ + "\"analyzing\" | \"reindexing\" | ", + "MlDataframeState" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DeleteDataFrameAnalyticsWithIndexStatus", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "DeleteDataFrameAnalyticsWithIndexStatus", + "description": [ + "\nInterface for DFA API response for deletion status\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DeleteDataFrameAnalyticsWithIndexStatus.success", + "type": "boolean", + "tags": [ + "type" + ], + "label": "success", + "description": [ + "\nSuccess" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DeleteDataFrameAnalyticsWithIndexStatus.error", + "type": "CompoundType", + "tags": [ + "type" + ], + "label": "error", + "description": [ + "\nOptional error" + ], + "signature": [ + "Boom", + " | ", + "ErrorResponseBase", + " | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.EvaluateMetrics", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "EvaluateMetrics", + "description": [ + "\nInterface for evalute metrics\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.EvaluateMetrics.classification", + "type": "Object", + "tags": [ + "type" + ], + "label": "classification", + "description": [ + "\nClassification evalute metrics" + ], + "signature": [ + "{ accuracy?: object | undefined; recall?: object | undefined; multiclass_confusion_matrix?: object | undefined; auc_roc?: { include_curve: boolean; class_name: string; } | undefined; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.EvaluateMetrics.regression", + "type": "Object", + "tags": [ + "type" + ], + "label": "regression", + "description": [ + "\nRegression evaluate metrics" + ], + "signature": [ + "{ r_squared: object; mse: object; msle: object; huber: object; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportance", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "FeatureImportance", + "description": [ + "\nES result feature importance interface\nTODO We should separate the interface because classes/importance\nisn't both optional but either/or.\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportance.feature_name", + "type": "string", + "tags": [ + "type" + ], + "label": "feature_name", + "description": [ + "\nThe feature name" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportance.classes", + "type": "Array", + "tags": [ + "type" + ], + "label": "classes", + "description": [ + "\nOptional classes" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.ClassFeatureImportance", + "text": "ClassFeatureImportance" + }, + "[] | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportance.importance", + "type": "number", + "tags": [ + "type" + ], + "label": "importance", + "description": [ + "\nOptional importance" + ], + "signature": [ + "number | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportanceClassBaseline", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "FeatureImportanceClassBaseline", + "description": [ + "\nBaseline interface for ES result feature importance class\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportanceClassBaseline.class_name", + "type": "CompoundType", + "tags": [ + "type" + ], + "label": "class_name", + "description": [ + "\nClass name" + ], + "signature": [ + "string | number | boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportanceClassBaseline.baseline", + "type": "number", + "tags": [ + "type" + ], + "label": "baseline", + "description": [ + "\nBaseline" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FieldSelectionItem", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef", + "extends" + ], + "label": "FieldSelectionItem", + "description": [ + "\nInterface for field selection item\n" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.FieldSelectionItem", + "text": "FieldSelectionItem" + }, + " extends Omit<", + "MlDataframeAnalyticsFieldSelection", + ", \"mapping_types\">" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FieldSelectionItem.mapping_types", + "type": "Array", + "tags": [ + "type" + ], + "label": "mapping_types", + "description": [ + "\nOptional mapping types" + ], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.OutlierAnalysis", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "OutlierAnalysis", + "description": [ + "\nInterface for outlier analysis job configuation\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.OutlierAnalysis.Unnamed", + "type": "IndexSignature", + "tags": [], + "label": "[key: string]: {}", + "description": [ + "\nKey spec for interface" + ], + "signature": [ + "[key: string]: {}" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.OutlierAnalysis.outlier_detection", + "type": "Object", + "tags": [ + "type" + ], + "label": "outlier_detection", + "description": [ + "\nOutlier detection options" + ], + "signature": [ + "{ compute_feature_influence?: boolean | undefined; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.PredictedClass", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "PredictedClass", + "description": [ + "\nInterface for predicted class\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.PredictedClass.predicted_class", + "type": "string", + "tags": [ + "type" + ], + "label": "predicted_class", + "description": [ + "\nPredicted class" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.PredictedClass.count", + "type": "number", + "tags": [ + "type" + ], + "label": "count", + "description": [ + "\nCount" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionAnalysis", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "RegressionAnalysis", + "description": [ + "\nInterface for regression analysis job configuation\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionAnalysis.Unnamed", + "type": "IndexSignature", + "tags": [], + "label": "[key: string]: Regression", + "description": [ + "\nKey spec for interface" + ], + "signature": [ + "[key: string]: Regression" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionAnalysis.regression", + "type": "Object", + "tags": [ + "type" + ], + "label": "regression", + "description": [ + "\nRegression options" + ], + "signature": [ + "Regression" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionFeatureImportanceBaseline", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "RegressionFeatureImportanceBaseline", + "description": [ + "\nBaseline interface for ES result regression feature importance\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionFeatureImportanceBaseline.baseline", + "type": "number", + "tags": [ + "type" + ], + "label": "baseline", + "description": [ + "\nBaseline" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionFeatureImportanceSummary", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "RegressionFeatureImportanceSummary", + "description": [ + "\nES result regression feature importance summary\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionFeatureImportanceSummary.max", + "type": "number", + "tags": [ + "type" + ], + "label": "max", + "description": [ + "\nMax feature importance" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionFeatureImportanceSummary.min", + "type": "number", + "tags": [ + "type" + ], + "label": "min", + "description": [ + "\nMin feature importance" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionFeatureImportanceSummary.mean_magnitude", + "type": "number", + "tags": [ + "type" + ], + "label": "mean_magnitude", + "description": [ + "\nMean magnitude" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionTotalFeatureImportance", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "RegressionTotalFeatureImportance", + "description": [ + "\nES result for regression total feature importance\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionTotalFeatureImportance.feature_name", + "type": "string", + "tags": [ + "type" + ], + "label": "feature_name", + "description": [ + "\nFeature name" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RegressionTotalFeatureImportance.importance", + "type": "Object", + "tags": [ + "type" + ], + "label": "importance", + "description": [ + "\nImportance" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.RegressionFeatureImportanceSummary", + "text": "RegressionFeatureImportanceSummary" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RocCurveItem", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "RocCurveItem", + "description": [ + "\nData item for ROC curve\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RocCurveItem.fpr", + "type": "number", + "tags": [ + "type" + ], + "label": "fpr", + "description": [ + "\nFPR" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RocCurveItem.threshold", + "type": "number", + "tags": [ + "type" + ], + "label": "threshold", + "description": [ + "\nThreshold" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.RocCurveItem.tpr", + "type": "number", + "tags": [ + "type" + ], + "label": "tpr", + "description": [ + "\nTPR" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TopClass", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "TopClass", + "description": [ + "\nES result top class interface\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TopClass.class_name", + "type": "CompoundType", + "tags": [ + "type" + ], + "label": "class_name", + "description": [ + "\nThe class name" + ], + "signature": [ + "string | number | boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TopClass.class_probability", + "type": "number", + "tags": [ + "type" + ], + "label": "class_probability", + "description": [ + "\nThe class probability" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TopClass.class_score", + "type": "number", + "tags": [ + "type" + ], + "label": "class_score", + "description": [ + "\nThe class score" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TrackTotalHitsSearchResponse", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "TrackTotalHitsSearchResponse", + "description": [ + "\nInterface for a search response's track total hits option\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TrackTotalHitsSearchResponse.hits", + "type": "Object", + "tags": [ + "type" + ], + "label": "hits", + "description": [ + "\nInner structure of the response" + ], + "signature": [ + "{ total: { value: number; relation: string; }; hits: any[]; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.UpdateDataFrameAnalyticsConfig", + "type": "Interface", + "tags": [ + "export", + "interface", + "typedef" + ], + "label": "UpdateDataFrameAnalyticsConfig", + "description": [ + "\nInterface for a requect object to update a DFA job\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.UpdateDataFrameAnalyticsConfig.allow_lazy_start", + "type": "string", + "tags": [ + "type" + ], + "label": "allow_lazy_start", + "description": [ + "\nOptional allow lazy start" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.UpdateDataFrameAnalyticsConfig.description", + "type": "string", + "tags": [ + "type" + ], + "label": "description", + "description": [ + "\nOptional description" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.UpdateDataFrameAnalyticsConfig.model_memory_limit", + "type": "string", + "tags": [ + "type" + ], + "label": "model_memory_limit", + "description": [ + "\nOptional model memory limit" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.UpdateDataFrameAnalyticsConfig.max_num_threads", + "type": "number", + "tags": [ + "type" + ], + "label": "max_num_threads", + "description": [ + "\nOptional max num threads" + ], + "signature": [ + "number | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.UpdateDataFrameAnalyticsConfig._meta", + "type": "Object", + "tags": [ + "type" + ], + "label": "_meta", + "description": [ + "\nOptional meta data" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.DataFrameAnalyticsMeta", + "text": "DataFrameAnalyticsMeta" + }, + " | undefined" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "enums": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ANALYSIS_ADVANCED_FIELDS", + "type": "Enum", + "tags": [ + "export", + "enum" + ], + "label": "ANALYSIS_ADVANCED_FIELDS", + "description": [ + "\nEnum for a DFA configuration's advanced fields\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.INDEX_STATUS", + "type": "Enum", + "tags": [ + "export", + "enum" + ], + "label": "INDEX_STATUS", + "description": [ + "\nEnum for index status\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.OUTLIER_ANALYSIS_METHOD", + "type": "Enum", + "tags": [ + "export", + "enum" + ], + "label": "OUTLIER_ANALYSIS_METHOD", + "description": [ + "\nEnum for a DFA configuration's outlier analysis method\n" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "misc": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.AnalysisConfig", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "AnalysisConfig", + "description": [ + "\nAlias of estypes.MlDataframeAnalysisContainer\n" + ], + "signature": [ + "MlDataframeAnalysisContainer" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalysisConfigType", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "DataFrameAnalysisConfigType", + "description": [ + "\nUnion type of DFA anlaysis config types\n" + ], + "signature": [ + "\"classification\" | \"outlier_detection\" | \"regression\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameAnalyticsId", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "DataFrameAnalyticsId", + "description": [ + "\nData frame analytics id" + ], + "signature": [ + "string" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DataFrameTaskStateType", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "DataFrameTaskStateType", + "description": [ + "\nUnion type of DFA task states\n" + ], + "signature": [ + "\"analyzing\" | \"reindexing\" | ", + "MlDataframeState" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DEFAULT_REGRESSION_COLUMNS", + "type": "number", + "tags": [ + "type" + ], + "label": "DEFAULT_REGRESSION_COLUMNS", + "description": [ + "\nDefault regression columns" + ], + "signature": [ + "8" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DEFAULT_RESULTS_FIELD", + "type": "string", + "tags": [ + "type" + ], + "label": "DEFAULT_RESULTS_FIELD", + "description": [ + "\nDefault results field\n" + ], + "signature": [ + "\"ml\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DfAnalyticsExplainResponse", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "DfAnalyticsExplainResponse", + "description": [ + "\nAlias for estypes.MlExplainDataFrameAnalyticsResponse\n" + ], + "signature": [ + "MlExplainDataFrameAnalyticsResponse" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FEATURE_IMPORTANCE", + "type": "string", + "tags": [ + "type" + ], + "label": "FEATURE_IMPORTANCE", + "description": [ + "\nFeature importance constant\n" + ], + "signature": [ + "\"feature_importance\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FEATURE_INFLUENCE", + "type": "string", + "tags": [ + "type" + ], + "label": "FEATURE_INFLUENCE", + "description": [ + "\nFeature influence constant\n" + ], + "signature": [ + "\"feature_influence\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportanceBaseline", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "FeatureImportanceBaseline", + "description": [ + "\nUnion type of feature importance baseline types\n" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.ClassificationFeatureImportanceBaseline", + "text": "ClassificationFeatureImportanceBaseline" + }, + " | ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.RegressionFeatureImportanceBaseline", + "text": "RegressionFeatureImportanceBaseline" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureImportanceClassName", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "FeatureImportanceClassName", + "description": [ + "\nUnion type for ES result feature importance class name\n" + ], + "signature": [ + "string | number | boolean" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.FeatureProcessor", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "FeatureProcessor", + "description": [ + "\nAlias for estypes.MlDataframeAnalysisFeatureProcessor\n" + ], + "signature": [ + "MlDataframeAnalysisFeatureProcessor" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.JobMapNodeTypes", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "JobMapNodeTypes", + "description": [ + "\nUnion type of JOB_MAP_NODE_TYPES\n" + ], + "signature": [ + "\"index\" | \"transform\" | \"analytics\" | \"trainedModel\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.MapElements", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "MapElements", + "description": [ + "\nUnion type of map node and edge elements\n" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.AnalyticsMapEdgeElement", + "text": "AnalyticsMapEdgeElement" + }, + " | ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.AnalyticsMapNodeElement", + "text": "AnalyticsMapNodeElement" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ML__ID_COPY", + "type": "string", + "tags": [ + "type" + ], + "label": "ML__ID_COPY", + "description": [ + "\nES field name for copy of the doc _id" + ], + "signature": [ + "\"ml__id_copy\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ML__INCREMENTAL_ID", + "type": "string", + "tags": [ + "type" + ], + "label": "ML__INCREMENTAL_ID", + "description": [ + "\nES field name for ML's incremental id" + ], + "signature": [ + "\"ml__incremental_id\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.NUM_TOP_FEATURE_IMPORTANCE_VALUES_MIN", + "type": "number", + "tags": [ + "type" + ], + "label": "NUM_TOP_FEATURE_IMPORTANCE_VALUES_MIN", + "description": [ + "\nMinimum value for feature importance\n" + ], + "signature": [ + "0" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.OUTLIER_SCORE", + "type": "string", + "tags": [ + "type" + ], + "label": "OUTLIER_SCORE", + "description": [ + "\nOutlier score constant\n" + ], + "signature": [ + "\"outlier_score\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TOP_CLASSES", + "type": "string", + "tags": [ + "type" + ], + "label": "TOP_CLASSES", + "description": [ + "\nTop classes constant\n" + ], + "signature": [ + "\"top_classes\"" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TopClasses", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "TopClasses", + "description": [ + "\nArray of TopClass\n" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.TopClass", + "text": "TopClass" + }, + "[]" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TotalFeatureImportance", + "type": "Type", + "tags": [ + "export", + "typedef" + ], + "label": "TotalFeatureImportance", + "description": [ + "\nUnion type of total feature importance types\n" + ], + "signature": [ + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.ClassificationTotalFeatureImportance", + "text": "ClassificationTotalFeatureImportance" + }, + " | ", + { + "pluginId": "@kbn/ml-data-frame-analytics-utils", + "scope": "common", + "docId": "kibKbnMlDataFrameAnalyticsUtilsPluginApi", + "section": "def-common.RegressionTotalFeatureImportance", + "text": "RegressionTotalFeatureImportance" + } + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/feature_importance.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TRAINING_PERCENT_MAX", + "type": "number", + "tags": [ + "type" + ], + "label": "TRAINING_PERCENT_MAX", + "description": [ + "\nMaximum training percent\n" + ], + "signature": [ + "100" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.TRAINING_PERCENT_MIN", + "type": "number", + "tags": [ + "type" + ], + "label": "TRAINING_PERCENT_MIN", + "description": [ + "\nMinimum training percent\n" + ], + "signature": [ + "1" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [ + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.ANALYSIS_CONFIG_TYPE", + "type": "Object", + "tags": [ + "type" + ], + "label": "ANALYSIS_CONFIG_TYPE", + "description": [ + "\nCustom enum for DFA config types\n" + ], + "signature": [ + "{ readonly OUTLIER_DETECTION: \"outlier_detection\"; readonly REGRESSION: \"regression\"; readonly CLASSIFICATION: \"classification\"; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.BASIC_NUMERICAL_TYPES", + "type": "Object", + "tags": [ + "type" + ], + "label": "BASIC_NUMERICAL_TYPES", + "description": [ + "\nSet of basic numerical types" + ], + "signature": [ + "Set<", + { + "pluginId": "@kbn/field-types", + "scope": "common", + "docId": "kibKbnFieldTypesPluginApi", + "section": "def-common.ES_FIELD_TYPES", + "text": "ES_FIELD_TYPES" + }, + ">" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.DATA_FRAME_TASK_STATE", + "type": "Object", + "tags": [ + "type" + ], + "label": "DATA_FRAME_TASK_STATE", + "description": [ + "\nCustom enum for DFA task states\n" + ], + "signature": [ + "{ readonly ANALYZING: \"analyzing\"; readonly FAILED: \"failed\"; readonly REINDEXING: \"reindexing\"; readonly STARTED: \"started\"; readonly STARTING: \"starting\"; readonly STOPPED: \"stopped\"; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.EXTENDED_NUMERICAL_TYPES", + "type": "Object", + "tags": [ + "type" + ], + "label": "EXTENDED_NUMERICAL_TYPES", + "description": [ + "\nSet of extended numerical types" + ], + "signature": [ + "Set<", + { + "pluginId": "@kbn/field-types", + "scope": "common", + "docId": "kibKbnFieldTypesPluginApi", + "section": "def-common.ES_FIELD_TYPES", + "text": "ES_FIELD_TYPES" + }, + ">" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/fields.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.INDEX_CREATED_BY", + "type": "Object", + "tags": [ + "type" + ], + "label": "INDEX_CREATED_BY", + "description": [ + "\nCustom enum for the metadata to be stored about which tool was used to create an index\n" + ], + "signature": [ + "{ readonly FILE_DATA_VISUALIZER: \"file-data-visualizer\"; readonly DATA_FRAME_ANALYTICS: \"data-frame-analytics\"; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-data-frame-analytics-utils", + "id": "def-common.JOB_MAP_NODE_TYPES", + "type": "Object", + "tags": [ + "type" + ], + "label": "JOB_MAP_NODE_TYPES", + "description": [ + "\nCustom enum for job map node types for the DFA map view\n" + ], + "signature": [ + "{ readonly ANALYTICS: \"analytics\"; readonly TRANSFORM: \"transform\"; readonly INDEX: \"index\"; readonly TRAINED_MODEL: \"trainedModel\"; }" + ], + "path": "x-pack/packages/ml/data_frame_analytics_utils/src/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx new file mode 100644 index 0000000000000..1bb9139d10268 --- /dev/null +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -0,0 +1,42 @@ +--- +#### +#### 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: kibKbnMlDataFrameAnalyticsUtilsPluginApi +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-01 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] +--- +import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; + + + +Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 153 | 1 | 0 | 0 | + +## Common + +### Objects + + +### Functions + + +### Interfaces + + +### Enums + + +### Consts, variables and types + + diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 7505ffae5ff6b..271578228bc80 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-05-31 +date: 2023-06-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_error_utils.devdocs.json b/api_docs/kbn_ml_error_utils.devdocs.json index 8872d1df30f9a..fa95dba9755f5 100644 --- a/api_docs/kbn_ml_error_utils.devdocs.json +++ b/api_docs/kbn_ml_error_utils.devdocs.json @@ -702,6 +702,8 @@ ], "signature": [ "string | ", + "ErrorResponseBase", + " | ", { "pluginId": "@kbn/ml-error-utils", "scope": "common", @@ -710,8 +712,6 @@ "text": "MLHttpFetchError" }, " | ", - "ErrorResponseBase", - " | ", "Boom", " | undefined" ], diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index fe72b3925815a..bb3675ce07104 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-05-31 +date: 2023-06-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 7eb7885d54678..59cc14eed997d 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-05-31 +date: 2023-06-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 4696616470625..7599757b564fc 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-05-31 +date: 2023-06-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 6ba96c4ae9f7c..76d9e4af29829 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-05-31 +date: 2023-06-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 4e0b0046f54d6..1182afa570707 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-05-31 +date: 2023-06-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 d2e448dab8a76..69b72b5e5d684 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-05-31 +date: 2023-06-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 2e7d06a964681..c2fd2851060ea 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-05-31 +date: 2023-06-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 8f4f988ea23cf..edfe6b7422732 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-05-31 +date: 2023-06-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 b90dff006c8a4..78468803da10e 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-05-31 +date: 2023-06-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 7e44dfb91230a..77f29115e9e0a 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-05-31 +date: 2023-06-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_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index b9992c934dbdb..f8bcf2c382b6b 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-05-31 +date: 2023-06-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 dc26fcc42a688..14c33505d3a14 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-05-31 +date: 2023-06-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 71e866e7cbebc..5cde757e9beb7 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-05-31 +date: 2023-06-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 34e750691ef6c..91125ad043603 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-05-31 +date: 2023-06-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 19c276e8fb77d..89d8d1b34f154 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-05-31 +date: 2023-06-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 956c61ac93605..cc8e0f1d02a17 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-05-31 +date: 2023-06-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 a7dacc730831d..1d85c7b083d67 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-05-31 +date: 2023-06-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 44e0210e7052b..d717ec2cd0e4c 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-05-31 +date: 2023-06-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 b7c27847870fc..4e532c163986e 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-05-31 +date: 2023-06-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 2579ef4f4447d..b260a85b93cce 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-05-31 +date: 2023-06-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 21e3498a839d1..887defebfbf6f 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-05-31 +date: 2023-06-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 86bd3829d2168..74f064ed0fbe6 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-05-31 +date: 2023-06-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 cebca1903f6d0..19f875216968c 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-05-31 +date: 2023-06-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 0cdb648b77537..80c20b22dde91 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-05-31 +date: 2023-06-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 af49fe0dc307a..9f9c29f368db8 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-05-31 +date: 2023-06-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 657905d2e6da0..496fb6389f842 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-05-31 +date: 2023-06-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 70192a23ddf48..099539e7f4bfc 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-05-31 +date: 2023-06-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 a3b0849a50d44..9c316ffab8778 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-05-31 +date: 2023-06-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 1cc94e6285219..0f642a7a1444c 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-05-31 +date: 2023-06-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 59e72f0e94483..f44cafb78e557 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-05-31 +date: 2023-06-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 5ef5e83d5359f..5573049bdf995 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-05-31 +date: 2023-06-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 01f956958304e..dfa4bc00ab1a8 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-05-31 +date: 2023-06-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 c4df626e2a253..762a4313085ef 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-05-31 +date: 2023-06-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 7e4c38a033c53..9a0a554038a2d 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-05-31 +date: 2023-06-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 ea5af22636583..9c15ab23f52b0 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-05-31 +date: 2023-06-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.devdocs.json b/api_docs/kbn_securitysolution_data_table.devdocs.json index 6cb74e6716356..a9bffd5d52c6c 100644 --- a/api_docs/kbn_securitysolution_data_table.devdocs.json +++ b/api_docs/kbn_securitysolution_data_table.devdocs.json @@ -238,15 +238,15 @@ "signature": [ "(headers: ", "ColumnHeaderOptions", - "[], browserFields: Readonly>>, isEventRenderedView?: boolean | undefined) => ", + ", isEventRenderedView?: boolean | undefined) => ", "ColumnHeaderOptions", "[]" ], @@ -278,15 +278,13 @@ "label": "browserFields", "description": [], "signature": [ - "Readonly>>" + "section": "def-common.BrowserFields", + "text": "BrowserFields" + } ], "path": "x-pack/packages/security-solution/data_table/components/data_table/column_headers/helpers.tsx", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index b5b3082f0e83b..a0fc2425b17a5 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-05-31 +date: 2023-06-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 06e802b6377f5..be6ce190a985d 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-05-31 +date: 2023-06-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 c4b75ebd0d45a..dbe5c7cf1ff87 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-05-31 +date: 2023-06-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 580b3c19446db..56a49291f5e9e 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-05-31 +date: 2023-06-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 321e2ce513796..612c0e8a22f58 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-05-31 +date: 2023-06-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 841b8edac6e3b..fb08428dcbca5 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-05-31 +date: 2023-06-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 c11718c7262cb..0d79755c69a63 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-05-31 +date: 2023-06-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 7d738a7c18344..18d7c549f5f46 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-05-31 +date: 2023-06-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 4f728ace2b15c..1962b2b3edda2 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-05-31 +date: 2023-06-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 73853081411db..880cc45d5ad9c 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-05-31 +date: 2023-06-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 140867b53e023..9377a9d836597 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-05-31 +date: 2023-06-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 4669537c928ce..d26c0d6fe22ab 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-05-31 +date: 2023-06-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 c876f50e2f68a..734255fda2450 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-05-31 +date: 2023-06-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 c278c03759fa4..f9bb00ccdad1a 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-05-31 +date: 2023-06-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 ecc79c0ca88ae..838b910132dff 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-05-31 +date: 2023-06-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 fb7d72f01158b..46b340404c4d8 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-05-31 +date: 2023-06-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 12ee41e85c954..ffe6c0ea05980 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-05-31 +date: 2023-06-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 efe1c7c123597..2e8ba47bf5a47 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-05-31 +date: 2023-06-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 66886a68121a4..a4def0085b858 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-05-31 +date: 2023-06-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 0a596916c0d63..fb36138a9dca8 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-05-31 +date: 2023-06-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 858670f5fb29d..ff8717ae1113d 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-05-31 +date: 2023-06-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 743f070f9c586..1fe0ecaeb9e59 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-05-31 +date: 2023-06-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 284b9f3266415..090c5b52ed4c8 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-05-31 +date: 2023-06-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 170d881bfdb3d..adcc78c91ca43 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-05-31 +date: 2023-06-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 6155558f8ea95..fba350b3f105e 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-05-31 +date: 2023-06-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 66a55ba81969e..5788d541cfc29 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-05-31 +date: 2023-06-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 c18178adbe6a9..a84071fb2f850 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-05-31 +date: 2023-06-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 70c3041d54fc3..46aeb9ca8bf94 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-05-31 +date: 2023-06-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 5cf6fbdaefb51..084f8512695ea 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-05-31 +date: 2023-06-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 1705f49753bf5..7aae6c2d3c545 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-05-31 +date: 2023-06-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 cbd7a457cedbf..655edcf17931e 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-05-31 +date: 2023-06-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 2cd215fdd8e14..6edd92fffac6f 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-05-31 +date: 2023-06-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 87ee4d6f2e1a6..ad3e395216c71 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-05-31 +date: 2023-06-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 d2341c308b281..03548a6d006d6 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-05-31 +date: 2023-06-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 ae727db7358d5..56def4cfd563c 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-05-31 +date: 2023-06-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 a6de9be61661b..0aba4db65c8b2 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-05-31 +date: 2023-06-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 3114750181fbb..6762f4ffe1cd0 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-05-31 +date: 2023-06-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 bb2e73b15bd31..47660dd9871f1 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-05-31 +date: 2023-06-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 0f652040604d0..edecc962de118 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-05-31 +date: 2023-06-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 4cbb0fcc4333a..1599e518f3853 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-05-31 +date: 2023-06-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 8ea48565cf934..4997cc85b5f32 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-05-31 +date: 2023-06-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 0abd24913da29..154c6f1c0c134 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-05-31 +date: 2023-06-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 1c2b0838959e8..99a220d43b59d 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-05-31 +date: 2023-06-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 fd5e7155b08b3..582ceeeb826b2 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-05-31 +date: 2023-06-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 6cc7e168236cd..1cfd04db7c0a2 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-05-31 +date: 2023-06-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 57b85943543f1..4e6d01866888f 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-05-31 +date: 2023-06-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 ec4f39c99467e..17d1853a319f0 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-05-31 +date: 2023-06-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 c22808c943706..450b902372030 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-05-31 +date: 2023-06-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 70c116170c5aa..4ea732df35f03 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-05-31 +date: 2023-06-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 b593a7a095e87..017d880ee90ff 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-05-31 +date: 2023-06-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 199e437c9ab92..1d80160d168a8 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-05-31 +date: 2023-06-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 09cd68fbb1b1d..e9c3a6b54237b 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-05-31 +date: 2023-06-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 18b8e50121a59..2a2f3ec640b59 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-05-31 +date: 2023-06-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 c105ca2c9d2ea..1371356d40c28 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-05-31 +date: 2023-06-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 ed9308488dac8..21adbfb9155a5 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-05-31 +date: 2023-06-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 293e931ae50ad..ebb2c980f62dc 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-05-31 +date: 2023-06-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 567dec2555491..deacac54844ae 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-05-31 +date: 2023-06-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 fb73340746e42..944b547c403a3 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-05-31 +date: 2023-06-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 279a4f8280826..7b74eb9629bb9 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-05-31 +date: 2023-06-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 ffcb9565fb6de..d40e9f8ddde90 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-05-31 +date: 2023-06-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 e0220e80c86e5..e5e1314e87663 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-05-31 +date: 2023-06-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 212767a837d95..12842ce069300 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-05-31 +date: 2023-06-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 ba35854323733..992a92cac959d 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-05-31 +date: 2023-06-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 baf1a72f235b6..e7dbdafbfcd9b 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-05-31 +date: 2023-06-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 47d5090e494d2..d67871512d18b 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-05-31 +date: 2023-06-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 8e9db99776093..36fa90f367846 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-05-31 +date: 2023-06-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 2b9b69cbe600e..942b41c7a4a1e 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-05-31 +date: 2023-06-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 96d6afd9e37f6..89250f07082b1 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-05-31 +date: 2023-06-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 5f46c2ecad206..59c1545c77c64 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-05-31 +date: 2023-06-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 325441998447a..f4f669a2d0b1b 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-05-31 +date: 2023-06-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.devdocs.json b/api_docs/kbn_text_based_editor.devdocs.json index 60a5a3a4ac391..1eb1abc6f8275 100644 --- a/api_docs/kbn_text_based_editor.devdocs.json +++ b/api_docs/kbn_text_based_editor.devdocs.json @@ -175,6 +175,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/text-based-editor", + "id": "def-public.TextBasedLanguagesEditorProps.detectTimestamp", + "type": "CompoundType", + "tags": [], + "label": "detectTimestamp", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/text-based-editor", "id": "def-public.TextBasedLanguagesEditorProps.errors", diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 38502d8dbadcc..7fc28eba573fc 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 14 | 0 | 13 | 0 | +| 15 | 0 | 14 | 0 | ## Client diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index b9ce2841c27ae..7f9bd4ca8d9b2 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-05-31 +date: 2023-06-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 badd091473acc..71e3cb0be0db1 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-05-31 +date: 2023-06-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 3576919a65e7e..41d8e02dc2462 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-05-31 +date: 2023-06-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 5fe6843a00aef..1884ee34a126d 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-05-31 +date: 2023-06-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 ce5cacd2646f8..1080b449da4af 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-05-31 +date: 2023-06-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 96f1dc93d26ec..cfcdd445bc958 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index f19f0b4c358f5..0528ffc11b1ab 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-05-31 +date: 2023-06-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 34b37cf8a8198..8ea4f206ce7f5 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-05-31 +date: 2023-06-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 756054d4d8812..6cf405400d42f 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-05-31 +date: 2023-06-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 83a13e439b3d0..a8ff9c3f59352 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-05-31 +date: 2023-06-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 50973074a0d9b..2091dbe711849 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-05-31 +date: 2023-06-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 e2339afdc2d37..6a5bc3f87ecd3 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-05-31 +date: 2023-06-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 b96e19f060bba..16bfd934084e5 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-05-31 +date: 2023-06-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 a271a4ba71a22..d48d890b84825 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-05-31 +date: 2023-06-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 a3d6b3d38031a..35395a19c1f90 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-05-31 +date: 2023-06-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 c7f9b661f4070..650c009db7115 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-05-31 +date: 2023-06-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 e8fa7dcc3b523..57d91cad28dfe 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -2976,7 +2976,7 @@ "section": "def-public.Visualization", "text": "Visualization" }, - " | (() => Promise<", + " | (() => Promise<", { "pluginId": "lens", "scope": "public", @@ -2984,7 +2984,7 @@ "section": "def-public.Visualization", "text": "Visualization" }, - ">)) => void" + ">)) => void" ], "path": "x-pack/plugins/lens/public/plugin.ts", "deprecated": false, @@ -3005,7 +3005,7 @@ "section": "def-public.Visualization", "text": "Visualization" }, - " | (() => Promise<", + " | (() => Promise<", { "pluginId": "lens", "scope": "public", @@ -3013,7 +3013,7 @@ "section": "def-public.Visualization", "text": "Visualization" }, - ">)" + ">)" ], "path": "x-pack/plugins/lens/public/plugin.ts", "deprecated": false, @@ -4981,7 +4981,7 @@ "section": "def-public.Visualization", "text": "Visualization" }, - "" + "" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -5010,7 +5010,7 @@ "\nInitialize is allowed to modify the state stored in memory. The initialize function\nis called with a previous state in two cases:\n- Loading from a saved visualization\n- When using suggestions, the suggested state is passed in" ], "signature": [ - "(addNewLayer: () => string, state?: T | P | undefined, mainPalette?: ", + "{ (addNewLayer: () => string, nonPersistedState?: T | undefined, mainPalette?: ", { "pluginId": "@kbn/coloring", "scope": "common", @@ -5018,7 +5018,17 @@ "section": "def-common.PaletteOutput", "text": "PaletteOutput" }, - "<{ [key: string]: unknown; }> | undefined, references?: ", + "<{ [key: string]: unknown; }> | undefined): T; (addNewLayer: () => string, persistedState: P, mainPalette?: ", + { + "pluginId": "@kbn/coloring", + "scope": "common", + "docId": "kibKbnColoringPluginApi", + "section": "def-common.PaletteOutput", + "text": "PaletteOutput" + }, + "<{ [key: string]: unknown; }> | undefined, annotationGroups?: ", + "AnnotationGroups", + " | undefined, references?: ", { "pluginId": "@kbn/core-saved-objects-common", "scope": "common", @@ -5026,138 +5036,11 @@ "section": "def-common.SavedObjectReference", "text": "SavedObjectReference" }, - "[] | undefined, initialContext?: ", - { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.VisualizeFieldContext", - "text": "VisualizeFieldContext" - }, - " | ", - "VisualizeEditorContext", - "<", - { - "pluginId": "visualizations", - "scope": "common", - "docId": "kibVisualizationsPluginApi", - "section": "def-common.Configuration", - "text": "Configuration" - }, - "> | undefined) => T" + "[] | undefined): T; }" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.Visualization.initialize.$1", - "type": "Function", - "tags": [], - "label": "addNewLayer", - "description": [], - "signature": [ - "() => string" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.initialize.$2", - "type": "CompoundType", - "tags": [], - "label": "state", - "description": [], - "signature": [ - "T | P | undefined" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.initialize.$3", - "type": "Object", - "tags": [], - "label": "mainPalette", - "description": [], - "signature": [ - { - "pluginId": "@kbn/coloring", - "scope": "common", - "docId": "kibKbnColoringPluginApi", - "section": "def-common.PaletteOutput", - "text": "PaletteOutput" - }, - "<{ [key: string]: unknown; }> | undefined" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.initialize.$4", - "type": "Array", - "tags": [], - "label": "references", - "description": [], - "signature": [ - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObjectReference", - "text": "SavedObjectReference" - }, - "[] | undefined" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.initialize.$5", - "type": "CompoundType", - "tags": [], - "label": "initialContext", - "description": [], - "signature": [ - { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.VisualizeFieldContext", - "text": "VisualizeFieldContext" - }, - " | ", - "VisualizeEditorContext", - "<", - { - "pluginId": "visualizations", - "scope": "common", - "docId": "kibVisualizationsPluginApi", - "section": "def-common.Configuration", - "text": "Configuration" - }, - "> | undefined" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - } - ], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "lens", @@ -5712,7 +5595,7 @@ "signature": [ "((state: T, layerId: string, type: ", "LayerType", - ", indexPatternId: string) => T) | undefined" + ", indexPatternId: string, extraArg?: ExtraAppendLayerArg | undefined) => T) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -5777,6 +5660,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.appendLayer.$5", + "type": "Uncategorized", + "tags": [], + "label": "extraArg", + "description": [], + "signature": [ + "ExtraAppendLayerArg | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [] @@ -5793,11 +5691,9 @@ "signature": [ "(state?: T | undefined, frame?: Pick<", "FramePublicAPI", - ", \"activeData\" | \"datasourceLayers\"> | undefined) => { type: ", - "LayerType", - "; label: string; icon?: ", - "IconType", - " | undefined; noDatasource?: boolean | undefined; disabled?: boolean | undefined; toolTipContent?: string | undefined; initialDimensions?: { columnId: string; groupId: string; staticValue?: unknown; autoTimeField?: boolean | undefined; }[] | undefined; canAddViaMenu?: boolean | undefined; }[]" + ", \"activeData\" | \"datasourceLayers\"> | undefined) => ", + "VisualizationLayerDescription", + "[]" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -5848,8 +5744,10 @@ "\nreturns a list of custom actions supported by the visualization layer.\nDefault actions like delete/clear are not included in this list and are managed by the editor frame" ], "signature": [ - "((layerId: string, state: T) => ", - "LayerActionFromVisualization", + "((layerId: string, state: T, setState: ", + "StateSetter", + ", isSaveable?: boolean | undefined) => ", + "LayerAction", "[]) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", @@ -5885,50 +5783,17 @@ "deprecated": false, "trackAdoption": false, "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.onLayerAction", - "type": "Function", - "tags": [], - "label": "onLayerAction", - "description": [ - "\nPerform state mutations in response to a layer action" - ], - "signature": [ - "((layerId: string, actionId: string, state: T) => T) | undefined" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.Visualization.onLayerAction.$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.onLayerAction.$2", - "type": "string", + "id": "def-public.Visualization.getSupportedActionsForLayer.$3", + "type": "Function", "tags": [], - "label": "actionId", + "label": "setState", "description": [], "signature": [ - "string" + "StateSetter", + "" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -5937,18 +5802,18 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.onLayerAction.$3", - "type": "Uncategorized", + "id": "def-public.Visualization.getSupportedActionsForLayer.$4", + "type": "CompoundType", "tags": [], - "label": "state", + "label": "isSaveable", "description": [], "signature": [ - "T" + "boolean | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, "trackAdoption": false, - "isRequired": true + "isRequired": false } ], "returnComment": [] @@ -6898,6 +6763,248 @@ ], "returnComment": [] }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent", + "type": "Function", + "tags": [], + "label": "getAddLayerButtonComponent", + "description": [], + "signature": [ + "((props: { supportedLayers: ", + "VisualizationLayerDescription", + "[]; addLayer: ", + "AddLayerFunction", + "; ensureIndexPattern: (specOrId: string | ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" + }, + ") => Promise; registerLibraryAnnotationGroup: (groupInfo: { id: string; group: ", + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + }, + "; }) => void; }) => JSX.Element | null) | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.supportedLayers", + "type": "Array", + "tags": [], + "label": "supportedLayers", + "description": [], + "signature": [ + "VisualizationLayerDescription", + "[]" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer", + "type": "Function", + "tags": [], + "label": "addLayer", + "description": [], + "signature": [ + "(layerType: ", + "LayerType", + ", extraArg?: unknown, ignoreInitialValues?: boolean | undefined) => void" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer.$1", + "type": "CompoundType", + "tags": [], + "label": "layerType", + "description": [], + "signature": [ + "\"data\" | \"annotations\" | \"metricTrendline\" | \"referenceLine\"" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer.$2", + "type": "Uncategorized", + "tags": [], + "label": "extraArg", + "description": [], + "signature": [ + "T | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer.$3", + "type": "CompoundType", + "tags": [], + "label": "ignoreInitialValues", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.ensureIndexPattern", + "type": "Function", + "tags": [], + "label": "ensureIndexPattern", + "description": [], + "signature": [ + "(specOrId: string | ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" + }, + ") => Promise" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.ensureIndexPattern.$1", + "type": "CompoundType", + "tags": [], + "label": "specOrId", + "description": [], + "signature": [ + "string | ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" + } + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.registerLibraryAnnotationGroup", + "type": "Function", + "tags": [], + "label": "registerLibraryAnnotationGroup", + "description": [], + "signature": [ + "(groupInfo: { id: string; group: ", + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + }, + "; }) => void" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.registerLibraryAnnotationGroup.$1", + "type": "Object", + "tags": [], + "label": "groupInfo", + "description": [], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.registerLibraryAnnotationGroup.$1.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.getAddLayerButtonComponent.$1.registerLibraryAnnotationGroup.$1.group", + "type": "Object", + "tags": [], + "label": "group", + "description": [], + "signature": [ + { + "pluginId": "eventAnnotation", + "scope": "common", + "docId": "kibEventAnnotationPluginApi", + "section": "def-common.EventAnnotationGroupConfig", + "text": "EventAnnotationGroupConfig" + } + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [] + } + ] + } + ], + "returnComment": [] + }, { "parentPluginId": "lens", "id": "def-public.Visualization.getUniqueLabels", @@ -7583,6 +7690,130 @@ ], "returnComment": [] }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.isEqual", + "type": "Function", + "tags": [], + "label": "isEqual", + "description": [], + "signature": [ + "((state1: P, references1: ", + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObjectReference", + "text": "SavedObjectReference" + }, + "[], state2: P, references2: ", + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObjectReference", + "text": "SavedObjectReference" + }, + "[], annotationGroups: ", + "AnnotationGroups", + ") => boolean) | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.isEqual.$1", + "type": "Uncategorized", + "tags": [], + "label": "state1", + "description": [], + "signature": [ + "P" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.isEqual.$2", + "type": "Array", + "tags": [], + "label": "references1", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObjectReference", + "text": "SavedObjectReference" + }, + "[]" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.isEqual.$3", + "type": "Uncategorized", + "tags": [], + "label": "state2", + "description": [], + "signature": [ + "P" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.isEqual.$4", + "type": "Array", + "tags": [], + "label": "references2", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObjectReference", + "text": "SavedObjectReference" + }, + "[]" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.isEqual.$5", + "type": "Object", + "tags": [], + "label": "annotationGroups", + "description": [], + "signature": [ + "AnnotationGroups" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "lens", "id": "def-public.Visualization.getVisualizationInfo", @@ -7788,116 +8019,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig", - "type": "Interface", - "tags": [], - "label": "XYAnnotationLayerConfig", - "description": [], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig.layerId", - "type": "string", - "tags": [], - "label": "layerId", - "description": [], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig.layerType", - "type": "string", - "tags": [], - "label": "layerType", - "description": [], - "signature": [ - "\"annotations\"" - ], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig.annotations", - "type": "Array", - "tags": [], - "label": "annotations", - "description": [], - "signature": [ - { - "pluginId": "eventAnnotation", - "scope": "common", - "docId": "kibEventAnnotationPluginApi", - "section": "def-common.EventAnnotationConfig", - "text": "EventAnnotationConfig" - }, - "[]" - ], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig.hide", - "type": "CompoundType", - "tags": [], - "label": "hide", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig.indexPatternId", - "type": "string", - "tags": [], - "label": "indexPatternId", - "description": [], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig.simpleView", - "type": "CompoundType", - "tags": [], - "label": "simpleView", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYAnnotationLayerConfig.ignoreGlobalFilters", - "type": "boolean", - "tags": [], - "label": "ignoreGlobalFilters", - "description": [], - "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.XYArgs", @@ -10508,6 +10629,23 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "lens", + "id": "def-public.XYAnnotationLayerConfig", + "type": "Type", + "tags": [], + "label": "XYAnnotationLayerConfig", + "description": [], + "signature": [ + "XYByValueAnnotationLayerConfig", + " | ", + "XYByReferenceAnnotationLayerConfig" + ], + "path": "x-pack/plugins/lens/public/visualizations/xy/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "lens", "id": "def-public.XYCurveType", diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 0d30b6f523cff..11e379a969914 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-05-31 +date: 2023-06-01 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 | |-------------------|-----------|------------------------|-----------------| -| 612 | 0 | 516 | 52 | +| 618 | 0 | 523 | 58 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 5dc158dc96d71..bcc1157308458 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-05-31 +date: 2023-06-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 830217864dc6b..2306089babca7 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-05-31 +date: 2023-06-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 dc8fcc0bcd8b7..648b2a2128afe 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-05-31 +date: 2023-06-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 e09df737fd827..e7f697e592ab9 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-05-31 +date: 2023-06-01 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 aa03264828686..eea3717205103 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-05-31 +date: 2023-06-01 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 3d7e71dda9ded..32fde7f29adbb 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-05-31 +date: 2023-06-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 6fb47f0098301..8643544873580 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-05-31 +date: 2023-06-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 9fc743f8094cb..e0c16e343e9ec 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-05-31 +date: 2023-06-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 8636041b41bd3..50d3ae17a2a2e 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-05-31 +date: 2023-06-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 5197d82b22fe7..c9a4932ba27b3 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-05-31 +date: 2023-06-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 b67d6cfef1599..c9f1ca8d0087c 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-05-31 +date: 2023-06-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 7b4f61215b894..4d6c1dfb60cb2 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-05-31 +date: 2023-06-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 54996bb6372ae..db1c584ef1155 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-05-31 +date: 2023-06-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 a62fab52f5966..f16c52121b7f4 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-05-31 +date: 2023-06-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 368d1b43fd950..90ed5935a3a01 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-05-31 +date: 2023-06-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 e0f52a40511de..503aeae5af659 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-05-31 +date: 2023-06-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 81c46cdbfcb5e..3a7bee5e2363f 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-05-31 +date: 2023-06-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 24b4e0cb7fc02..d72885816feee 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-05-31 +date: 2023-06-01 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 | |--------------|----------|------------------------| -| 618 | 511 | 38 | +| 620 | 513 | 38 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 69782 | 522 | 60084 | 1349 | +| 69976 | 523 | 60134 | 1359 | ## Plugin Directory @@ -41,15 +41,15 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 41 | 0 | 11 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Chat available on Elastic Cloud deployments for quicker assistance. | 1 | 0 | 0 | 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 | -| | [@elastic/sec-cloudnative-integrations](https://github.com/orgs/elastic/teams/sec-cloudnative-integrations) | Defend for containers (D4C) | 15 | 0 | 4 | 2 | +| | [@elastic/sec-cloudnative-integrations](https://github.com/orgs/elastic/teams/sec-cloudnative-integrations) | Defend for containers (D4C) | 12 | 0 | 4 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Provides the necessary APIs to implement A/B testing scenarios, fetching the variations in configuration and reporting back metrics to track conversion rates of the experiments. | 12 | 0 | 0 | 0 | | cloudFullStory | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | When Kibana runs on Elastic Cloud, this plugin registers FullStory as a shipper for telemetry. | 0 | 0 | 0 | 0 | | cloudGainsight | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | When Kibana runs on Elastic Cloud, this plugin registers Gainsight as a shipper for telemetry. | 0 | 0 | 0 | 0 | | cloudLinks | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Adds the links to the Elastic Cloud console | 0 | 0 | 0 | 0 | -| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | The cloud security posture plugin | 17 | 0 | 2 | 2 | +| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | The cloud security posture plugin | 14 | 0 | 2 | 2 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 13 | 0 | 13 | 1 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Content management app | 149 | 0 | 126 | 6 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 306 | 0 | 299 | 14 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 304 | 0 | 297 | 14 | | crossClusterReplication | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | | customBranding | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Enables customization of Kibana | 0 | 0 | 0 | 0 | | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 274 | 0 | 255 | 1 | @@ -65,12 +65,12 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 96 | 0 | 75 | 7 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 546 | 11 | 444 | 4 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 546 | 11 | 442 | 4 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 51 | 0 | 44 | 0 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 9 | 0 | 9 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 115 | 3 | 111 | 3 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 172 | 30 | 172 | 3 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 204 | 30 | 204 | 3 | | | [@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 | @@ -92,7 +92,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 239 | 0 | 24 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Simple UI for managing files in Kibana | 2 | 1 | 2 | 0 | -| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1159 | 3 | 1045 | 31 | +| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1156 | 3 | 1041 | 31 | | ftrApis | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 0 | 0 | 0 | 0 | @@ -114,7 +114,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. | 612 | 0 | 516 | 52 | +| | [@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. | 618 | 0 | 523 | 58 | | | [@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 | @@ -137,11 +137,12 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 218 | 8 | 164 | 11 | | | [@elastic/profiling-ui](https://github.com/orgs/elastic/teams/profiling-ui) | - | 15 | 2 | 15 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 36 | 0 | 16 | 0 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 38 | 0 | 18 | 3 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Currently PDF, PNG or CSV export types for the reporting plugin | 4 | 0 | 4 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 21 | 0 | 21 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 263 | 0 | 234 | 14 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 24 | 0 | 19 | 2 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 127 | 2 | 116 | 4 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 129 | 2 | 118 | 4 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 44 | 0 | 44 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 154 | 0 | 140 | 2 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 79 | 0 | 73 | 3 | @@ -168,15 +169,15 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 31 | 0 | 26 | 6 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 1 | 0 | 1 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 5 | 0 | 0 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 16 | 0 | 16 | 0 | -| | [@elastic/protections-experience](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 35 | 0 | 14 | 5 | -| | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 257 | 1 | 214 | 20 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 17 | 0 | 17 | 0 | +| | [@elastic/protections-experience](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 30 | 0 | 14 | 5 | +| | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 259 | 1 | 216 | 21 | | | [@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) | - | 544 | 11 | 518 | 49 | | | [@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) | Contains functionality for the field list which can be integrated into apps | 293 | 0 | 267 | 8 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list which can be integrated into apps | 296 | 0 | 270 | 8 | | | [@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-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 | @@ -435,7 +436,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 47 | 0 | 40 | 0 | | | [@elastic/actionable-observability](https://github.com/orgs/elastic/teams/actionable-observability) | - | 9 | 0 | 9 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 52 | 12 | 43 | 0 | -| | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | - | 39 | 0 | 39 | 4 | +| | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | - | 43 | 0 | 43 | 4 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 13 | 0 | 13 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 85 | 0 | 77 | 5 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 41 | 2 | 35 | 0 | @@ -448,6 +449,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@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) | - | 93 | 2 | 61 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 142 | 3 | 0 | 0 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 153 | 1 | 0 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 52 | 0 | 4 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 36 | 0 | 8 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 2 | 0 | 0 | 0 | @@ -554,7 +556,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 282 | 4 | 238 | 12 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 135 | 5 | 103 | 2 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 1 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 14 | 0 | 13 | 0 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 15 | 0 | 14 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 72 | 0 | 55 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 39 | 0 | 25 | 1 | | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | - | 86 | 0 | 86 | 1 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 951500f4241a9..bd4d7e12b1ff0 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-05-31 +date: 2023-06-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 e6b9aa366dd3f..0a8885ca21206 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-05-31 +date: 2023-06-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 90d5947aa188d..d0cb58f9ab876 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-05-31 +date: 2023-06-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 c90cc3c0d1ad2..0c5a1bfef37a3 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.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 | |-------------------|-----------|------------------------|-----------------| -| 36 | 0 | 16 | 0 | +| 38 | 0 | 18 | 3 | ## Client diff --git a/api_docs/reporting_export_types.devdocs.json b/api_docs/reporting_export_types.devdocs.json new file mode 100644 index 0000000000000..d298d7bd6d398 --- /dev/null +++ b/api_docs/reporting_export_types.devdocs.json @@ -0,0 +1,96 @@ +{ + "id": "reportingExportTypes", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "reportingExportTypes", + "id": "def-server.ExportTypesPluginSetup", + "type": "Interface", + "tags": [], + "label": "ExportTypesPluginSetup", + "description": [], + "path": "x-pack/plugins/reporting_export_types/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "reportingExportTypes", + "id": "def-server.ExportTypesPluginSetup.reporting", + "type": "Object", + "tags": [], + "label": "reporting", + "description": [], + "signature": [ + { + "pluginId": "reporting", + "scope": "server", + "docId": "kibReportingPluginApi", + "section": "def-server.ReportingSetup", + "text": "ReportingSetup" + } + ], + "path": "x-pack/plugins/reporting_export_types/server/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "reportingExportTypes", + "id": "def-server.ExportTypesPluginStart", + "type": "Interface", + "tags": [], + "label": "ExportTypesPluginStart", + "description": [], + "path": "x-pack/plugins/reporting_export_types/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "reportingExportTypes", + "id": "def-server.ExportTypesPluginStart.reporting", + "type": "Object", + "tags": [], + "label": "reporting", + "description": [], + "signature": [ + { + "pluginId": "reporting", + "scope": "server", + "docId": "kibReportingPluginApi", + "section": "def-server.ReportingSetup", + "text": "ReportingSetup" + } + ], + "path": "x-pack/plugins/reporting_export_types/server/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx new file mode 100644 index 0000000000000..2ed31850c11f9 --- /dev/null +++ b/api_docs/reporting_export_types.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: kibReportingExportTypesPluginApi +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-01 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] +--- +import reportingExportTypesObj from './reporting_export_types.devdocs.json'; + +Currently PDF, PNG or CSV export types for the reporting plugin + +Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 4 | 0 | 4 | 0 | + +## Server + +### Interfaces + + diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 1aaa260836e0d..17b9a5349f929 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-05-31 +date: 2023-06-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 7ff29c176f0e8..58242b3f3f6ba 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-05-31 +date: 2023-06-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 ac55b014e489f..b9a18af31359d 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.devdocs.json b/api_docs/saved_objects.devdocs.json index 91c323dab911d..9c1668d649f44 100644 --- a/api_docs/saved_objects.devdocs.json +++ b/api_docs/saved_objects.devdocs.json @@ -58,6 +58,14 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx" }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx" + }, + { + "plugin": "lens", + "path": "x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx" + }, { "plugin": "discover", "path": "src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx" @@ -152,6 +160,17 @@ "path": "src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "savedObjects", + "id": "def-public.SavedObjectSaveModal.state.hasAttemptedSubmit", + "type": "boolean", + "tags": [], + "label": "hasAttemptedSubmit", + "description": [], + "path": "src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx", + "deprecated": false, + "trackAdoption": false } ] }, @@ -2191,6 +2210,17 @@ "path": "src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "savedObjects", + "id": "def-public.SaveModalState.hasAttemptedSubmit", + "type": "boolean", + "tags": [], + "label": "hasAttemptedSubmit", + "description": [], + "path": "src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 236b2b2e1b644..bc28d89180084 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.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 | |-------------------|-----------|------------------------|-----------------| -| 127 | 2 | 116 | 4 | +| 129 | 2 | 118 | 4 | ## Client diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index fd7bd50f3d552..d7d7d96c7eada 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-05-31 +date: 2023-06-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 86ef24ad52918..1e1e06531df97 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-05-31 +date: 2023-06-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 70632cec48226..08d1123bf228f 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.devdocs.json b/api_docs/saved_objects_tagging_oss.devdocs.json index 773e92b87b37e..97b83dc8f3ea2 100644 --- a/api_docs/saved_objects_tagging_oss.devdocs.json +++ b/api_docs/saved_objects_tagging_oss.devdocs.json @@ -1377,7 +1377,7 @@ "section": "def-common.Tag", "text": "Tag" }, - " | { type: \"__create_option__\"; }>> & { initialSelection: string[]; onTagsSelected: (ids: string[]) => void; }" + " | { type: \"__create_option__\"; }>> & { initialSelection: string[]; onTagsSelected: (ids: string[]) => void; markOptional?: boolean | undefined; }" ], "path": "src/plugins/saved_objects_tagging_oss/public/api.ts", "deprecated": false, diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 44418359e6c32..916aec50d0537 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-05-31 +date: 2023-06-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 3d46583594e1f..7bc5576a95f44 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-05-31 +date: 2023-06-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 fa2eac1f3ffbf..07db4887399c8 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-05-31 +date: 2023-06-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 4e8c49d0bc624..f228aed64488d 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-05-31 +date: 2023-06-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 2c75f9cc66f20..e799b33b7af8e 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-05-31 +date: 2023-06-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 7943d0b97fb74..de2ba917781e0 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-05-31 +date: 2023-06-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 19d196e6422e4..b44b3bceeaf98 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-05-31 +date: 2023-06-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 aef82a5672432..389de2609cc3c 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-05-31 +date: 2023-06-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 62fe5f7e54bfe..c2b7513114b07 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-05-31 +date: 2023-06-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 3a8edca6e8216..2300e3d5d34ef 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-05-31 +date: 2023-06-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 11cf7d53adcb8..32fc231c964d0 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-05-31 +date: 2023-06-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 f03870d5f29af..8138d7ff5d4a5 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-05-31 +date: 2023-06-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 96de2fcf93a61..f6e53320b996c 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-05-31 +date: 2023-06-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 0c009c97a1890..35bea5077acad 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-05-31 +date: 2023-06-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 5875510a08635..0a7ca7aa6a77b 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-05-31 +date: 2023-06-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 c43802f1fc90a..8a54c86066e26 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-05-31 +date: 2023-06-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 74d671278f9d2..b768146800fce 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-05-31 +date: 2023-06-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 26fb7bfed8663..ec5caf8886745 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-05-31 +date: 2023-06-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 21c961a2f4097..7da191fe160d2 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-05-31 +date: 2023-06-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 80b8b96bc234e..42f8c3e81dd02 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-05-31 +date: 2023-06-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 2147ebb74e46c..133fc8e9d0615 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.devdocs.json b/api_docs/text_based_languages.devdocs.json index 581b217b86366..e5f1b90b12a78 100644 --- a/api_docs/text_based_languages.devdocs.json +++ b/api_docs/text_based_languages.devdocs.json @@ -182,6 +182,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "textBasedLanguages", + "id": "def-public.TextBasedLanguagesEditorProps.detectTimestamp", + "type": "CompoundType", + "tags": [], + "label": "detectTimestamp", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "textBasedLanguages", "id": "def-public.TextBasedLanguagesEditorProps.errors", diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index ec6285085a33c..c4ffe4458ea5f 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 16 | 0 | 16 | 0 | +| 17 | 0 | 17 | 0 | ## Client diff --git a/api_docs/threat_intelligence.devdocs.json b/api_docs/threat_intelligence.devdocs.json index 688ae390b26a3..e61ea9b2ea265 100644 --- a/api_docs/threat_intelligence.devdocs.json +++ b/api_docs/threat_intelligence.devdocs.json @@ -3,45 +3,6 @@ "client": { "classes": [], "functions": [ - { - "parentPluginId": "threatIntelligence", - "id": "def-public.getSecuritySolutionDeepLink", - "type": "Function", - "tags": [], - "label": "getSecuritySolutionDeepLink", - "description": [ - "\nGets the threat intelligence properties of a TI page for deep linking in the security solution." - ], - "signature": [ - "(threatIntelligencePage: \"indicators\") => TIDeepLink" - ], - "path": "x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "threatIntelligence", - "id": "def-public.getSecuritySolutionDeepLink.$1", - "type": "string", - "tags": [], - "label": "threatIntelligencePage", - "description": [ - "the name of the threat intelligence page." - ], - "signature": [ - "\"indicators\"" - ], - "path": "x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [ - "a {@link TIDeepLink }" - ], - "initialIsOpen": false - }, { "parentPluginId": "threatIntelligence", "id": "def-public.getSecuritySolutionLink", @@ -80,62 +41,6 @@ "a {@link TILinkItem }" ], "initialIsOpen": false - }, - { - "parentPluginId": "threatIntelligence", - "id": "def-public.getSecuritySolutionNavTab", - "type": "Function", - "tags": [], - "label": "getSecuritySolutionNavTab", - "description": [ - "\nGets the threat intelligence properties of a TI page for navigation in the old security solution navigation." - ], - "signature": [ - "(threatIntelligencePage: \"indicators\", basePath: string) => TINavTab" - ], - "path": "x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "threatIntelligence", - "id": "def-public.getSecuritySolutionNavTab.$1", - "type": "string", - "tags": [], - "label": "threatIntelligencePage", - "description": [ - "the name of the threat intelligence page." - ], - "signature": [ - "\"indicators\"" - ], - "path": "x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "threatIntelligence", - "id": "def-public.getSecuritySolutionNavTab.$2", - "type": "string", - "tags": [], - "label": "basePath", - "description": [ - "the base path for links." - ], - "signature": [ - "string" - ], - "path": "x-pack/plugins/threat_intelligence/public/utils/security_solution_links.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [ - "a {@link TINavTab }" - ], - "initialIsOpen": false } ], "interfaces": [ diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index c6206cf14e3b1..f75a4b46d1708 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/protections-experience](https://github.com/orgs/elastic/teams/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 35 | 0 | 14 | 5 | +| 30 | 0 | 14 | 5 | ## Client diff --git a/api_docs/timelines.devdocs.json b/api_docs/timelines.devdocs.json index 03f2681b5c646..a1d96c65ee1d5 100644 --- a/api_docs/timelines.devdocs.json +++ b/api_docs/timelines.devdocs.json @@ -1469,18 +1469,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/containers/source/index.tsx" }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/containers/source/index.tsx" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/containers/source/index.tsx" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/containers/source/index.tsx" - }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/common/components/event_details/types.ts" @@ -1633,7 +1621,7 @@ "label": "fields", "description": [], "signature": [ - "{ readonly [x: string]: Partial<", + "{ [x: string]: Partial<", { "pluginId": "timelines", "scope": "common", @@ -3029,6 +3017,54 @@ "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "timelines", + "id": "def-common.TimelineEqlRequestOptions.runtime_mappings", + "type": "Object", + "tags": [], + "label": "runtime_mappings", + "description": [], + "signature": [ + "Record & { type: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.RuntimePrimitiveTypes", + "text": "RuntimePrimitiveTypes" + }, + "; }> | undefined" + ], + "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "timelines", + "id": "def-common.TimelineEqlRequestOptions.body", + "type": "CompoundType", + "tags": [], + "label": "body", + "description": [], + "signature": [ + "(Omit<", + "EqlSearchRequest", + ", \"body\"> & EqlBody & { runtime_mappings?: ", + "RunTimeMappings", + "; }) | undefined" + ], + "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -3242,9 +3278,23 @@ "label": "runtimeMappings", "description": [], "signature": [ - "{ [x: string]: ", - "MappingRuntimeField", - "; }" + "Record & { type: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.RuntimePrimitiveTypes", + "text": "RuntimePrimitiveTypes" + }, + "; }> | undefined" ], "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts", "deprecated": false, @@ -4221,7 +4271,7 @@ "label": "BrowserFields", "description": [], "signature": [ - "{ readonly [x: string]: Partial<", + "{ [x: string]: Partial<", { "pluginId": "timelines", "scope": "common", @@ -4425,7 +4475,11 @@ }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/containers/source/index.tsx" + "path": "x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/common/containers/source/use_data_view.tsx" }, { "plugin": "securitySolution", @@ -4721,15 +4775,15 @@ ], "signature": [ "EuiDataGridCellValueElementProps", - " & { asPlainText?: boolean | undefined; browserFields?: Readonly>> | undefined; data: ", + " | undefined; data: ", { "pluginId": "timelines", "scope": "common", diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 44a574270a79c..367bcfdb6c916 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-threat-hunting-investigations](https://github.com/org | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 257 | 1 | 214 | 20 | +| 259 | 1 | 216 | 21 | ## Client diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index c0c7ec1b5c388..2577eef194d84 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-05-31 +date: 2023-06-01 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 cef02e5a0c0ab..3266aa83a1a42 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-05-31 +date: 2023-06-01 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 64b75c90dd5f0..f94b9407f201d 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-05-31 +date: 2023-06-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 f983586baf8e7..dc5c689869290 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.devdocs.json b/api_docs/unified_field_list.devdocs.json index f592e3401ae0e..d936dbf5d94c1 100644 --- a/api_docs/unified_field_list.devdocs.json +++ b/api_docs/unified_field_list.devdocs.json @@ -1612,7 +1612,7 @@ "\nMemorizes current query, filters and absolute date range" ], "signature": [ - "({ data }: ", + "({ data, listenToSearchSessionUpdates, }: ", { "pluginId": "unifiedFieldList", "scope": "public", @@ -1638,7 +1638,7 @@ "id": "def-public.useQuerySubscriber.$1", "type": "Object", "tags": [], - "label": "{ data }", + "label": "{\n data,\n listenToSearchSessionUpdates = true,\n}", "description": [], "signature": [ { @@ -2970,15 +2970,15 @@ "label": "renderFieldItem", "description": [], "signature": [ - "(params: { field: T; hideDetails?: boolean | undefined; itemIndex: number; groupIndex: number; groupName: ", + "(params: ", { "pluginId": "unifiedFieldList", "scope": "public", "docId": "kibUnifiedFieldListPluginApi", - "section": "def-public.FieldsGroupNames", - "text": "FieldsGroupNames" + "section": "def-public.RenderFieldItemParams", + "text": "RenderFieldItemParams" }, - "; fieldSearchHighlight?: string | undefined; }) => JSX.Element" + ") => JSX.Element" ], "path": "src/plugins/unified_field_list/public/components/field_list_grouped/field_list_grouped.tsx", "deprecated": false, @@ -2993,15 +2993,14 @@ "label": "params", "description": [], "signature": [ - "{ field: T; hideDetails?: boolean | undefined; itemIndex: number; groupIndex: number; groupName: ", { "pluginId": "unifiedFieldList", "scope": "public", "docId": "kibUnifiedFieldListPluginApi", - "section": "def-public.FieldsGroupNames", - "text": "FieldsGroupNames" + "section": "def-public.RenderFieldItemParams", + "text": "RenderFieldItemParams" }, - "; fieldSearchHighlight?: string | undefined; }" + "" ], "path": "src/plugins/unified_field_list/public/components/field_list_grouped/fields_accordion.tsx", "deprecated": false, @@ -4901,6 +4900,20 @@ "path": "src/plugins/unified_field_list/public/hooks/use_query_subscriber.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.QuerySubscriberParams.listenToSearchSessionUpdates", + "type": "CompoundType", + "tags": [], + "label": "listenToSearchSessionUpdates", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/unified_field_list/public/hooks/use_query_subscriber.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -4999,6 +5012,114 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.RenderFieldItemParams", + "type": "Interface", + "tags": [], + "label": "RenderFieldItemParams", + "description": [], + "signature": [ + { + "pluginId": "unifiedFieldList", + "scope": "public", + "docId": "kibUnifiedFieldListPluginApi", + "section": "def-public.RenderFieldItemParams", + "text": "RenderFieldItemParams" + }, + "" + ], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.RenderFieldItemParams.field", + "type": "Uncategorized", + "tags": [], + "label": "field", + "description": [], + "signature": [ + "T" + ], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.RenderFieldItemParams.hideDetails", + "type": "CompoundType", + "tags": [], + "label": "hideDetails", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.RenderFieldItemParams.itemIndex", + "type": "number", + "tags": [], + "label": "itemIndex", + "description": [], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.RenderFieldItemParams.groupIndex", + "type": "number", + "tags": [], + "label": "groupIndex", + "description": [], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.RenderFieldItemParams.groupName", + "type": "Enum", + "tags": [], + "label": "groupName", + "description": [], + "signature": [ + { + "pluginId": "unifiedFieldList", + "scope": "public", + "docId": "kibUnifiedFieldListPluginApi", + "section": "def-public.FieldsGroupNames", + "text": "FieldsGroupNames" + } + ], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "unifiedFieldList", + "id": "def-public.RenderFieldItemParams.fieldSearchHighlight", + "type": "string", + "tags": [], + "label": "fieldSearchHighlight", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/unified_field_list/public/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "unifiedFieldList", "id": "def-public.VisualizeInformation", @@ -5326,86 +5447,10 @@ "server": { "classes": [], "functions": [], - "interfaces": [ - { - "parentPluginId": "unifiedFieldList", - "id": "def-server.PluginSetup", - "type": "Interface", - "tags": [], - "label": "PluginSetup", - "description": [], - "path": "src/plugins/unified_field_list/server/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "initialIsOpen": false - }, - { - "parentPluginId": "unifiedFieldList", - "id": "def-server.PluginStart", - "type": "Interface", - "tags": [], - "label": "PluginStart", - "description": [], - "path": "src/plugins/unified_field_list/server/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "unifiedFieldList", - "id": "def-server.PluginStart.dataViews", - "type": "Object", - "tags": [], - "label": "dataViews", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "server", - "docId": "kibDataViewsPluginApi", - "section": "def-server.DataViewsServerPluginStart", - "text": "DataViewsServerPluginStart" - } - ], - "path": "src/plugins/unified_field_list/server/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - } - ], + "interfaces": [], "enums": [], "misc": [], - "objects": [], - "setup": { - "parentPluginId": "unifiedFieldList", - "id": "def-server.UnifiedFieldListServerPluginSetup", - "type": "Interface", - "tags": [], - "label": "UnifiedFieldListServerPluginSetup", - "description": [], - "path": "src/plugins/unified_field_list/server/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "lifecycle": "setup", - "initialIsOpen": true - }, - "start": { - "parentPluginId": "unifiedFieldList", - "id": "def-server.UnifiedFieldListServerPluginStart", - "type": "Interface", - "tags": [], - "label": "UnifiedFieldListServerPluginStart", - "description": [], - "path": "src/plugins/unified_field_list/server/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "lifecycle": "start", - "initialIsOpen": true - } + "objects": [] }, "common": { "classes": [], diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index 1aa12a5fa6144..6eb8d4b0cf096 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2023-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.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 | |-------------------|-----------|------------------------|-----------------| -| 293 | 0 | 267 | 8 | +| 296 | 0 | 270 | 8 | ## Client @@ -43,17 +43,6 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k ### Consts, variables and types -## Server - -### Setup - - -### Start - - -### Interfaces - - ## Common ### Consts, variables and types diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 7b4ac5c8a5487..08a6613700e36 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-05-31 +date: 2023-06-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 37cabd884296e..daf054e434529 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-05-31 +date: 2023-06-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 d457f26ebc55b..43616c2e477a3 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-05-31 +date: 2023-06-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 ff12bab28faac..83011a25bb0da 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-05-31 +date: 2023-06-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 44a433e56d4a1..bd2b45d228c23 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-05-31 +date: 2023-06-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 890b4063b7a29..7492b9b3e5870 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-05-31 +date: 2023-06-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 a6d3a49cd7b12..3dc4bf9763347 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-05-31 +date: 2023-06-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 47767ba2eff29..2f8acdbe2ffd9 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-05-31 +date: 2023-06-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 1c0df77e3eb80..c13bf1951d0f6 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-05-31 +date: 2023-06-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 b16bf486841a5..d92b8580be006 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-05-31 +date: 2023-06-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 ed6e30f62469c..a8a150d2e931d 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-05-31 +date: 2023-06-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 630f6af7d24be..8a5297cbb3e2b 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-05-31 +date: 2023-06-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 e3c0c2e6ba425..474975e74c54d 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-05-31 +date: 2023-06-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 053368cdad387..2a97b3bae2e37 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-05-31 +date: 2023-06-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 11ac350ad642b..19e96aeeda883 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-05-31 +date: 2023-06-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 b4ab21b59db92..f51cd60882b39 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-05-31 +date: 2023-06-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 d4c3638136772..9a32b2043f858 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-05-31 +date: 2023-06-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 e0d32cc189c66..6fa6c37e63325 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-05-31 +date: 2023-06-01 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 109e67b4643ca815b913036ad9788f557f2c6661 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 1 Jun 2023 01:50:49 -0400 Subject: [PATCH 13/31] SO model versions: add validation for mapping additions (#158714) ## Summary Add validation to ensure that mappings added via a `mappings_addition` type change are also present in the type's full mappings. (just an extra layer of protection for when the teams will switch to using the new API) --- .../validate_migration.test.ts | 97 +++++++++++++++++++ .../document_migrator/validate_migrations.ts | 68 ++++++++++++- 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migration.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migration.test.ts index d44932f879232..8fbaf06b56f80 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migration.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migration.test.ts @@ -236,6 +236,103 @@ describe('validateTypeMigrations', () => { }); }); + describe('modelVersions mapping additions', () => { + it('throws when registering mapping additions not present in the global mappings', () => { + const type = createType({ + name: 'foo', + switchToModelVersionAt: '8.8.0', + modelVersions: { + '1': { + changes: [ + { + type: 'mappings_addition', + addedMappings: { + field2: { type: 'text' }, + }, + }, + ], + }, + }, + mappings: { + properties: { + field1: { type: 'text' }, + }, + }, + }); + + expect(() => validate({ type, kibanaVersion: '3.2.3' })).toThrowErrorMatchingInlineSnapshot( + `"Type foo: mappings added on model versions not present on the global mappings definition: field2.type"` + ); + }); + + it('does not throw when registering mapping additions are present in the global mappings', () => { + const type = createType({ + name: 'foo', + switchToModelVersionAt: '8.8.0', + modelVersions: { + '1': { + changes: [ + { + type: 'mappings_addition', + addedMappings: { + field2: { type: 'text' }, + }, + }, + ], + }, + '2': { + changes: [ + { + type: 'mappings_addition', + addedMappings: { + field3: { type: 'text' }, + }, + }, + ], + }, + }, + mappings: { + properties: { + field1: { type: 'text' }, + field2: { type: 'text' }, + field3: { type: 'text' }, + }, + }, + }); + + expect(() => validate({ type, kibanaVersion: '3.2.3' })).not.toThrow(); + }); + + it('throws when registering mapping additions different than the global mappings', () => { + const type = createType({ + name: 'foo', + switchToModelVersionAt: '8.8.0', + modelVersions: { + '1': { + changes: [ + { + type: 'mappings_addition', + addedMappings: { + field2: { type: 'boolean' }, + }, + }, + ], + }, + }, + mappings: { + properties: { + field1: { type: 'text' }, + field2: { type: 'text' }, + }, + }, + }); + + expect(() => validate({ type, kibanaVersion: '3.2.3' })).toThrowErrorMatchingInlineSnapshot( + `"Type foo: mappings added on model versions differs from the global mappings definition: field2.type"` + ); + }); + }); + describe('convertToMultiNamespaceTypeVersion', () => { it(`validates convertToMultiNamespaceTypeVersion can only be used with namespaceType 'multiple' or 'multiple-isolated'`, () => { const type = createType({ diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migrations.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migrations.ts index e3c528e0050e0..42ee0ad6ae8e1 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migrations.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/validate_migrations.ts @@ -7,9 +7,18 @@ */ import Semver from 'semver'; +import { getFlattenedObject } from '@kbn/std'; import type { SavedObjectsNamespaceType } from '@kbn/core-saved-objects-common'; -import type { SavedObjectsType } from '@kbn/core-saved-objects-server'; +import type { + SavedObjectsType, + SavedObjectsTypeMappingDefinition, + SavedObjectsModelVersionMap, +} from '@kbn/core-saved-objects-server'; import { assertValidModelVersion } from '@kbn/core-saved-objects-base-server-internal'; +import { + SavedObjectsModelChange, + SavedObjectsModelMappingsAdditionChange, +} from '@kbn/core-saved-objects-server'; /** * Validates the consistency of the given type for use with the document migrator. @@ -87,6 +96,9 @@ export function validateTypeMigrations({ if (minVersion > 1) { throw new Error(`Type ${type.name}: model versioning must start with version 1`); } + + validateAddedMappings(type.name, type.mappings, modelVersionMap); + const missingVersions = getMissingVersions( minVersion, maxVersion, @@ -114,6 +126,60 @@ export function validateTypeMigrations({ } } +function isMappingAddition( + change: SavedObjectsModelChange +): change is SavedObjectsModelMappingsAdditionChange { + return change.type === 'mappings_addition'; +} + +const validateAddedMappings = ( + typeName: string, + mappings: SavedObjectsTypeMappingDefinition, + modelVersions: SavedObjectsModelVersionMap +) => { + const flattenedMappings = new Map(Object.entries(getFlattenedObject(mappings.properties))); + + const mappingAdditionChanges = Object.values(modelVersions) + .flatMap((version) => version.changes) + .filter(isMappingAddition); + const addedMappings = mappingAdditionChanges.reduce((map, change) => { + const flattened = getFlattenedObject(change.addedMappings); + Object.keys(flattened).forEach((key) => { + map.set(key, flattened[key]); + }); + return map; + }, new Map()); + + const missingMappings: string[] = []; + const mappingsWithDifferentValues: string[] = []; + + for (const [key, value] of addedMappings.entries()) { + if (!flattenedMappings.has(key)) { + missingMappings.push(key); + } else { + const valueInMappings = flattenedMappings.get(key); + if (valueInMappings !== value) { + mappingsWithDifferentValues.push(key); + } + } + } + + if (missingMappings.length) { + throw new Error( + `Type ${typeName}: mappings added on model versions not present on the global mappings definition: ${missingMappings.join( + ',' + )}` + ); + } + if (mappingsWithDifferentValues.length) { + throw new Error( + `Type ${typeName}: mappings added on model versions differs from the global mappings definition: ${mappingsWithDifferentValues.join( + ',' + )}` + ); + } +}; + const assertObjectOrFunction = (entity: any, prefix: string) => { if (!entity || (typeof entity !== 'function' && typeof entity !== 'object')) { throw new Error(`${prefix} Got! ${typeof entity}, ${JSON.stringify(entity)}.`); From 72fa06535bf48e6ccd650dcc7efe2a8fadb430d5 Mon Sep 17 00:00:00 2001 From: Ersin Erdal <92688503+ersin-erdal@users.noreply.github.com> Date: Thu, 1 Jun 2023 09:23:00 +0200 Subject: [PATCH 14/31] [EventLog] Use performance.now() rather than Date.now() to calculate elapsed time in tests (#158721) Resolves: #156061 Since all the failed CI results show actual elapsed time as `19` rather than `20` (expected), the issue seems like an inaccurate time calculation caused by `Date.now()` method. Replacing `Date.now()` with the more precise `performance.now()` method may solve the problem. --- x-pack/plugins/event_log/server/es/init.test.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/event_log/server/es/init.test.ts b/x-pack/plugins/event_log/server/es/init.test.ts index 7280849a8cac0..137bf17247f6e 100644 --- a/x-pack/plugins/event_log/server/es/init.test.ts +++ b/x-pack/plugins/event_log/server/es/init.test.ts @@ -455,8 +455,7 @@ describe('parseIndexAliases', () => { }); }); -// FLAKY: https://github.com/elastic/kibana/issues/156061 -describe.skip('retries', () => { +describe('retries', () => { let esContext = contextMock.create(); // set up context APIs to return defaults indicating already created beforeEach(() => { @@ -472,9 +471,9 @@ describe.skip('retries', () => { test('createIlmPolicyIfNotExists with 1 retry', async () => { esContext.esAdapter.doesIlmPolicyExist.mockRejectedValueOnce(new Error('retry 1')); - const timeStart = Date.now(); + const timeStart = performance.now(); await initializeEs(esContext); - const timeElapsed = Date.now() - timeStart; + const timeElapsed = performance.now() - timeStart; expect(timeElapsed).toBeGreaterThanOrEqual(MOCK_RETRY_DELAY); @@ -492,9 +491,9 @@ describe.skip('retries', () => { esContext.esAdapter.doesIndexTemplateExist.mockRejectedValueOnce(new Error('retry 2a')); esContext.esAdapter.doesIndexTemplateExist.mockRejectedValueOnce(new Error('retry 2b')); - const timeStart = Date.now(); + const timeStart = performance.now(); await initializeEs(esContext); - const timeElapsed = Date.now() - timeStart; + const timeElapsed = performance.now() - timeStart; expect(timeElapsed).toBeGreaterThanOrEqual(MOCK_RETRY_DELAY * (1 + 2)); @@ -518,9 +517,9 @@ describe.skip('retries', () => { // make sure it only tries 5 times - this one should not be reported esContext.esAdapter.doesAliasExist.mockRejectedValueOnce(new Error('retry 5f')); - const timeStart = Date.now(); + const timeStart = performance.now(); await initializeEs(esContext); - const timeElapsed = Date.now() - timeStart; + const timeElapsed = performance.now() - timeStart; expect(timeElapsed).toBeGreaterThanOrEqual(MOCK_RETRY_DELAY * (1 + 2 + 4 + 8)); From eed0d015318577b7cf9a4527d7f8b036a1071800 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Thu, 1 Jun 2023 10:09:26 +0200 Subject: [PATCH 15/31] [Lens] Make reference lines use the correct formatter when configured (#158266) ## Summary Fixes #156771 This PR add the correct logic to extract the table column formatter, when set, and use it within a reference line context. If no formatter is set then the group/axis formatter is used. Included required changes directly in this PR to make it reviewable. Screenshot 2023-05-31 at 14 53 40 ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Stratoula Kalafateli Co-authored-by: Peter Pisljar --- .../expression_functions/reference_line.ts | 9 ++- .../common/types/expression_functions.ts | 7 +- .../reference_lines/reference_line.tsx | 7 +- .../reference_lines/reference_line_layer.tsx | 7 +- .../reference_lines/reference_lines.test.tsx | 69 ++++++++++++++++++- .../reference_lines/reference_lines.tsx | 3 +- .../components/reference_lines/utils.tsx | 30 +++++++- .../public/components/xy_chart.tsx | 9 ++- .../format_column/format_column.test.ts | 28 +++----- .../format_column/format_column_fn.ts | 7 +- 10 files changed, 146 insertions(+), 30 deletions(-) diff --git a/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line.ts b/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line.ts index 93832291b9835..a4f615ba0e869 100644 --- a/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line.ts +++ b/src/plugins/chart_expressions/expression_xy/common/expression_functions/reference_line.ts @@ -119,11 +119,18 @@ export const referenceLineFunction: ReferenceLineFn = { ? false : args.textVisibility; + const valueMeta = + args.forAccessor && table + ? table.columns.find(({ id }) => id === args.forAccessor)?.meta + : undefined; + return { type: REFERENCE_LINE, layerType: LayerTypes.REFERENCELINE, lineLength: table?.rows.length ?? 0, - decorations: [{ ...args, textVisibility, type: EXTENDED_REFERENCE_LINE_DECORATION_CONFIG }], + decorations: [ + { ...args, textVisibility, type: EXTENDED_REFERENCE_LINE_DECORATION_CONFIG, valueMeta }, + ], }; }, }; diff --git a/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts b/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts index 0a2c00ed4f17f..55fd63786570b 100644 --- a/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts +++ b/src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts @@ -9,7 +9,11 @@ import { type AxisProps, HorizontalAlignment, Position, VerticalAlignment } from '@elastic/charts'; import type { $Values } from '@kbn/utility-types'; import type { PaletteOutput } from '@kbn/coloring'; -import type { Datatable, ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common'; +import type { + Datatable, + DatatableColumnMeta, + ExpressionFunctionDefinition, +} from '@kbn/expressions-plugin/common'; import { LegendSize } from '@kbn/visualizations-plugin/common'; import { EventAnnotationOutput } from '@kbn/event-annotation-plugin/common'; import { ExpressionValueVisDimension } from '@kbn/visualizations-plugin/common'; @@ -334,6 +338,7 @@ export interface ReferenceLineArgs extends Omit>; xAxisFormatter: FieldFormat; + formatters: FormattersMap; axesConfiguration: GroupsConfiguration; isHorizontal: boolean; nextValue?: number; @@ -28,6 +29,7 @@ export const ReferenceLine: FC = ({ layer, axesConfiguration, xAxisFormatter, + formatters, paddingMap, isHorizontal, nextValue, @@ -47,7 +49,8 @@ export const ReferenceLine: FC = ({ const axisGroup = getAxisGroupForReferenceLine(axesConfiguration, decorationConfig, isHorizontal); - const formatter = axisGroup?.formatter || xAxisFormatter; + const formatter = + formatters[decorationConfig.forAccessor] || axisGroup?.formatter || xAxisFormatter; const id = `${layer.layerId}-${value}`; const name = decorationConfig.textVisibility ? columnToLabelMap[decorationConfig.forAccessor] diff --git a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_line_layer.tsx b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_line_layer.tsx index 6c3792d6e7ea3..e34469ab74423 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_line_layer.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_line_layer.tsx @@ -13,13 +13,14 @@ import { Position } from '@elastic/charts'; import { ReferenceLineLayerConfig } from '../../../common/types'; import { ReferenceLineAnnotations } from './reference_line_annotations'; import { LayerAccessorsTitles, GroupsConfiguration, AxesMap } from '../../helpers'; -import { getAxisGroupForReferenceLine } from './utils'; +import { FormattersMap, getAxisGroupForReferenceLine } from './utils'; interface ReferenceLineLayerProps { layer: ReferenceLineLayerConfig; paddingMap: Partial>; isHorizontal: boolean; titles?: LayerAccessorsTitles; + formatters: FormattersMap; xAxisFormatter: FieldFormat; axesConfiguration: GroupsConfiguration; yAxesMap: AxesMap; @@ -28,6 +29,7 @@ interface ReferenceLineLayerProps { export const ReferenceLineLayer: FC = ({ layer, axesConfiguration, + formatters, xAxisFormatter, paddingMap, isHorizontal, @@ -59,7 +61,8 @@ export const ReferenceLineLayer: FC = ({ isHorizontal ); - const formatter = axisGroup?.formatter || xAxisFormatter; + const formatter = + formatters[decorationConfig.forAccessor] || axisGroup?.formatter || xAxisFormatter; const name = columnToLabelMap[decorationConfig.forAccessor] ?? titles?.yTitles?.[decorationConfig.forAccessor]; diff --git a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.test.tsx b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.test.tsx index 810705a71fa3e..320b51310bb76 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.test.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.test.tsx @@ -47,7 +47,8 @@ const data: Datatable = { }; function createLayers( - decorations: ReferenceLineLayerArgs['decorations'] + decorations: ReferenceLineLayerArgs['decorations'], + table?: Datatable ): ReferenceLineLayerConfig[] { return [ { @@ -56,7 +57,7 @@ function createLayers( decorations, type: 'referenceLineLayer', layerType: LayerTypes.REFERENCELINE, - table: data, + table: table || data, }, ]; } @@ -96,6 +97,7 @@ describe('ReferenceLines', () => { beforeEach(() => { defaultProps = { + formatters: {}, xAxisFormatter: { convert: jest.fn((x) => x) } as unknown as FieldFormat, isHorizontal: false, axesConfiguration: [ @@ -163,6 +165,68 @@ describe('ReferenceLines', () => { ).not.toThrow(); }); + it('should prefer column formatter over x axis default one', () => { + const convertLeft = jest.fn((x) => `left-${x}`); + const convertRight = jest.fn((x) => `right-${x}`); + const wrapper = shallow( + ({ + id, + name: `Static value: ${row[id]}`, + meta: { + type: 'number', + params: { id: 'number', params: { formatOverride: true, pattern: '0.0' } }, + }, + })), + } + )} + /> + ); + const referenceLineLayer = wrapper.find(ReferenceLineLayer).dive(); + const annotations = referenceLineLayer.find(ReferenceLineAnnotations); + expect(annotations.first().dive().find(LineAnnotation).prop('dataValues')).toEqual( + expect.arrayContaining([{ dataValue: 5, details: `left-5`, header: undefined }]) + ); + expect(annotations.last().dive().find(RectAnnotation).prop('dataValues')).toEqual( + expect.arrayContaining([ + { + coordinates: { x0: undefined, x1: undefined, y0: 5, y1: undefined }, + details: `right-5`, + header: undefined, + }, + ]) + ); + + expect(convertLeft).toHaveBeenCalled(); + expect(convertRight).toHaveBeenCalled(); + expect(defaultProps.xAxisFormatter.convert).not.toHaveBeenCalled(); + }); + it.each([ ['yAccessorLeft', 'above'], ['yAccessorLeft', 'below'], @@ -482,6 +546,7 @@ describe('ReferenceLines', () => { beforeEach(() => { defaultProps = { + formatters: {}, xAxisFormatter: { convert: jest.fn((x) => x) } as unknown as FieldFormat, isHorizontal: false, axesConfiguration: [ diff --git a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.tsx b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.tsx index bb250c0a133bf..2b3f0b225c8e1 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/reference_lines.tsx @@ -20,7 +20,7 @@ import { } from '../../helpers'; import { ReferenceLineLayer } from './reference_line_layer'; import { ReferenceLine } from './reference_line'; -import { getNextValuesForReferenceLines } from './utils'; +import { FormattersMap, getNextValuesForReferenceLines } from './utils'; export interface ReferenceLinesProps { layers: CommonXYReferenceLineLayerConfig[]; @@ -30,6 +30,7 @@ export interface ReferenceLinesProps { paddingMap: Partial>; titles?: LayersAccessorsTitles; yAxesMap: AxesMap; + formatters: FormattersMap; } export const ReferenceLines = ({ layers, titles = {}, ...rest }: ReferenceLinesProps) => { diff --git a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/utils.tsx b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/utils.tsx index 33c513a42c603..be70777f76f22 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/utils.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/reference_lines/utils.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { Position } from '@elastic/charts'; import { euiLightVars } from '@kbn/ui-theme'; -import { FieldFormat } from '@kbn/field-formats-plugin/common'; +import { FieldFormat, FormatFactory } from '@kbn/field-formats-plugin/common'; import { groupBy, orderBy } from 'lodash'; import { IconPosition, @@ -17,6 +17,7 @@ import { FillStyle, ExtendedReferenceLineDecorationConfig, ReferenceLineDecorationConfig, + CommonXYReferenceLineLayerConfig, } from '../../../common/types'; import { FillStyles } from '../../../common/constants'; import { @@ -27,6 +28,7 @@ import { getAxisPosition, getOriginalAxisPosition, AxesMap, + isReferenceLine, } from '../../helpers'; import type { ReferenceLineAnnotationConfig } from './reference_line_annotations'; @@ -241,3 +243,29 @@ export function getAxisGroupForReferenceLine( getAxisPosition(decorationConfig.position ?? Position.Left, shouldRotate) === axis.position ); } + +export type FormattersMap = Record; + +export function getReferenceLinesFormattersMap( + referenceLinesLayers: CommonXYReferenceLineLayerConfig[], + formatFactory: FormatFactory +): FormattersMap { + const formattersMap: Record = {}; + for (const layer of referenceLinesLayers) { + if (isReferenceLine(layer)) { + for (const { valueMeta, forAccessor } of layer.decorations) { + if (valueMeta?.params?.params?.formatOverride) { + formattersMap[forAccessor] = formatFactory(valueMeta.params); + } + } + } else { + for (const { forAccessor } of layer.decorations || []) { + const columnFormat = layer.table.columns.find(({ id }) => id === forAccessor)?.meta.params; + if (columnFormat?.params?.formatOverride) { + formattersMap[forAccessor] = formatFactory(columnFormat); + } + } + } + } + return formattersMap; +} diff --git a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx index 8d903a233fee7..feca72389a35f 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx @@ -93,6 +93,7 @@ import { ReferenceLines, computeChartMargins, getAxisGroupForReferenceLine, + getReferenceLinesFormattersMap, } from './reference_lines'; import { visualizationDefinitions } from '../definitions'; import { CommonXYLayerConfig } from '../../common/types'; @@ -452,7 +453,7 @@ export function XYChart({ : Position.Bottom, })), ...groupedLineAnnotations, - ].filter(Boolean); + ].filter(nonNullable); const shouldHideDetails = annotations?.layers && annotations.layers.length > 0 @@ -800,6 +801,11 @@ export function XYChart({ 'settings' ) as Partial; + const referenceLinesFormatters = getReferenceLinesFormattersMap( + referenceLineLayers, + formatFactory + ); + return (

{showLegend !== undefined && uiState && ( @@ -1073,6 +1079,7 @@ export function XYChart({ paddingMap={linesPaddings} titles={titles} yAxesMap={yAxesMap} + formatters={referenceLinesFormatters} /> ) : null} {(rangeAnnotations.length || lineAnnotations.length) && isTimeViz ? ( diff --git a/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts b/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts index bb01864c4f090..892783e41788c 100644 --- a/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts +++ b/x-pack/plugins/lens/common/expressions/format_column/format_column.test.ts @@ -46,9 +46,7 @@ describe('format_column', () => { const result = await fn(datatable, { columnId: 'test', format: 'number' }); expect(result.columns[0].meta.params).toEqual({ id: 'number', - params: { - pattern: '0,0.00', - }, + params: { formatOverride: true, pattern: '0,0.00' }, }); }); @@ -57,9 +55,7 @@ describe('format_column', () => { const result = await fn(datatable, { columnId: 'test', format: 'number', decimals: 5 }); expect(result.columns[0].meta.params).toEqual({ id: 'number', - params: { - pattern: '0,0.00000', - }, + params: { formatOverride: true, pattern: '0,0.00000' }, }); }); @@ -76,9 +72,8 @@ describe('format_column', () => { params: { suffixString: 'ABC', id: 'number', - params: { - pattern: '0,0.00000', - }, + formatOverride: true, + params: { formatOverride: true, pattern: '0,0.00000' }, }, }); }); @@ -88,9 +83,7 @@ describe('format_column', () => { const result = await fn(datatable, { columnId: 'test', format: 'number', decimals: 0 }); expect(result.columns[0].meta.params).toEqual({ id: 'number', - params: { - pattern: '0,0', - }, + params: { formatOverride: true, pattern: '0,0' }, }); }); @@ -175,6 +168,7 @@ describe('format_column', () => { id: 'suffix', params: { suffixString: 'abc', + formatOverride: true, id: 'wrapper', params: { wrapperParam: 123, @@ -229,9 +223,8 @@ describe('format_column', () => { params: { wrapperParam: 123, id: 'number', - params: { - pattern: '0,0.00000', - }, + params: { formatOverride: true, pattern: '0,0.00000' }, + formatOverride: true, pattern: '0,0.00000', }, }); @@ -256,9 +249,8 @@ describe('format_column', () => { paramsPerField: [ { id: 'number', - params: { - pattern: '0,0.00000', - }, + params: { formatOverride: true, pattern: '0,0.00000' }, + formatOverride: true, pattern: '0,0.00000', }, ], diff --git a/x-pack/plugins/lens/common/expressions/format_column/format_column_fn.ts b/x-pack/plugins/lens/common/expressions/format_column/format_column_fn.ts index 74c5d2a53c5c2..ce70a4d9f8ff3 100644 --- a/x-pack/plugins/lens/common/expressions/format_column/format_column_fn.ts +++ b/x-pack/plugins/lens/common/expressions/format_column/format_column_fn.ts @@ -33,7 +33,10 @@ export const formatColumnFn: FormatColumnExpressionFunction['fn'] = ( if (supportedFormats[format]) { const serializedFormat: SerializedFieldFormat = { id: supportedFormats[format].formatId, - params: { pattern: supportedFormats[format].decimalsToPattern(decimals) }, + params: { + pattern: supportedFormats[format].decimalsToPattern(decimals), + formatOverride: true, + }, }; return withParams(col, serializedFormat as Record); } else if (format) { @@ -56,6 +59,7 @@ export const formatColumnFn: FormatColumnExpressionFunction['fn'] = ( if (format && supportedFormats[format]) { const customParams = { pattern: supportedFormats[format].decimalsToPattern(decimals), + formatOverride: true, }; // Some parent formatters are multi-fields and wrap the custom format into a "paramsPerField" // property. Here the format is passed to this property to make it work properly @@ -128,6 +132,7 @@ export const formatColumnFn: FormatColumnExpressionFunction['fn'] = ( params: { ...col.meta.params, suffixString: suffix, + formatOverride: true, }, }, }, From e4be75943757c382fb42bf11c974cc6f260fb902 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 1 Jun 2023 11:24:59 +0100 Subject: [PATCH 16/31] [ML] Increasing calendar events request limit (#158726) Fixes https://github.com/elastic/kibana/issues/158712 Increasing the limit for getting all events, the default is `100`, which can easily be passed. Also increasing the size for getting all calendars, for consistency. --- x-pack/plugins/ml/server/models/calendar/calendar_manager.ts | 2 +- x-pack/plugins/ml/server/models/calendar/event_manager.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts b/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts index 03ad89ba5b02c..37b76013d6808 100644 --- a/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts +++ b/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts @@ -47,7 +47,7 @@ export class CalendarManager { } async getAllCalendars() { - const body = await this._mlClient.getCalendars({ body: { page: { from: 0, size: 1000 } } }); + const body = await this._mlClient.getCalendars({ body: { page: { from: 0, size: 10000 } } }); const events: ScheduledEvent[] = await this._eventManager.getAllEvents(); const calendars: Calendar[] = body.calendars as Calendar[]; diff --git a/x-pack/plugins/ml/server/models/calendar/event_manager.ts b/x-pack/plugins/ml/server/models/calendar/event_manager.ts index ae92be8d84eea..8aa48a05fdc31 100644 --- a/x-pack/plugins/ml/server/models/calendar/event_manager.ts +++ b/x-pack/plugins/ml/server/models/calendar/event_manager.ts @@ -28,6 +28,7 @@ export class EventManager { const body = await this._mlClient.getCalendarEvents({ calendar_id: calendarId, job_id: jobId, + size: 10000, }); return body.events; From 35dae4c9700268a45babd1415aed89e13a06b466 Mon Sep 17 00:00:00 2001 From: Chenhui Wang <54903978+wangch079@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:37:39 +0800 Subject: [PATCH 17/31] Modify scheduling structure of Connector index (#158640) # Part of https://github.com/elastic/enterprise-search-team/issues/4628 ## Summary This PR modifies the structure of `scheduling` in index `.elastic-connectors`. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../index_management/setup_indices.test.ts | 20 +++++++++++++++++-- .../server/index_management/setup_indices.ts | 20 +++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts index 5b575a7733f7f..299fa7d1d1484 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts @@ -165,8 +165,24 @@ describe('Setup Indices', () => { }, scheduling: { properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, + access_control: { + properties: { + enabled: { type: 'boolean' }, + interval: { type: 'text' }, + }, + }, + incremental: { + properties: { + enabled: { type: 'boolean' }, + interval: { type: 'text' }, + }, + }, + full: { + properties: { + enabled: { type: 'boolean' }, + interval: { type: 'text' }, + }, + }, }, }, service_type: { type: 'keyword' }, diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts index a58963134fdee..3de57c8fc2a65 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts @@ -154,8 +154,24 @@ const connectorMappingsProperties: Record = { }, scheduling: { properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, + access_control: { + properties: { + enabled: { type: 'boolean' }, + interval: { type: 'text' }, + }, + }, + incremental: { + properties: { + enabled: { type: 'boolean' }, + interval: { type: 'text' }, + }, + }, + full: { + properties: { + enabled: { type: 'boolean' }, + interval: { type: 'text' }, + }, + }, }, }, service_type: { type: 'keyword' }, From 9b330e493216e8dde3166451e4714966f63f5ab7 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 1 Jun 2023 06:45:27 -0400 Subject: [PATCH 18/31] improve TSDoc for model version types (#158799) ## Summary Just add some more documentation and examples to the model version types --- .../core-saved-objects-server/index.ts | 1 + .../src/model_version/index.ts | 1 + .../src/model_version/model_change.ts | 39 ++++++++++++++- .../src/model_version/model_version.ts | 35 +++++++++++-- .../src/model_version/schemas.ts | 49 ++++++++++++++----- .../src/saved_objects_type.ts | 20 ++++---- 6 files changed, 118 insertions(+), 27 deletions(-) diff --git a/packages/core/saved-objects/core-saved-objects-server/index.ts b/packages/core/saved-objects/core-saved-objects-server/index.ts index be67c64f9b7ce..53d01003357c1 100644 --- a/packages/core/saved-objects/core-saved-objects-server/index.ts +++ b/packages/core/saved-objects/core-saved-objects-server/index.ts @@ -136,6 +136,7 @@ export type { SavedObjectModelDataBackfillFn, SavedObjectsModelVersionSchemaDefinitions, SavedObjectModelVersionForwardCompatibilityFn, + SavedObjectModelVersionForwardCompatibilityObjectSchema, SavedObjectModelVersionForwardCompatibilitySchema, } from './src/model_version'; diff --git a/packages/core/saved-objects/core-saved-objects-server/src/model_version/index.ts b/packages/core/saved-objects/core-saved-objects-server/src/model_version/index.ts index 8bf11ca83067a..ec864bf158ca1 100644 --- a/packages/core/saved-objects/core-saved-objects-server/src/model_version/index.ts +++ b/packages/core/saved-objects/core-saved-objects-server/src/model_version/index.ts @@ -31,5 +31,6 @@ export type { export type { SavedObjectsModelVersionSchemaDefinitions, SavedObjectModelVersionForwardCompatibilitySchema, + SavedObjectModelVersionForwardCompatibilityObjectSchema, SavedObjectModelVersionForwardCompatibilityFn, } from './schemas'; diff --git a/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_change.ts b/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_change.ts index fb18ac9035b86..fb4745929ae30 100644 --- a/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_change.ts +++ b/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_change.ts @@ -27,6 +27,21 @@ export type SavedObjectsModelChange = /** * A {@link SavedObjectsModelChange | model change} adding new mappings. * + * @example + * ```ts + * let change: SavedObjectsModelMappingsAdditionChange = { + * type: 'mappings_addition', + * addedMappings: { + * newField: { type: 'text' }, + * existingNestedField: { + * properties: { + * newNestedProp: { type: 'keyword' }, + * }, + * }, + * }, + * }; + * ``` + * * @remark when adding mappings, {@link SavedObjectsType.mappings | the type mappings} must also be updated accordingly. * Overall, the type's mapping represents the latest version of the mappings, where the model changes * represent the changes of mappings between two versions. @@ -42,8 +57,17 @@ export interface SavedObjectsModelMappingsAdditionChange { } /** - * A {@link SavedObjectsModelChange | model change} flagging mappings as being deprecated. - * Deprecated mappings should no longer be used and will eventually be deleted later. + * A {@link SavedObjectsModelChange | model change} flagging mappings as being no longer used. + * + * @example + * ```ts + * let change: SavedObjectsModelMappingsDeprecationChange = { + * type: 'mappings_deprecation', + * deprecatedMappings: ['someDeprecatedField', 'someNested.deprecatedField'], + * }; + * ``` + * + * @remark Deprecated mappings will eventually be deleted later. */ export interface SavedObjectsModelMappingsDeprecationChange { type: 'mappings_deprecation'; @@ -56,6 +80,17 @@ export interface SavedObjectsModelMappingsDeprecationChange { /** * A {@link SavedObjectsModelChange | model change} used to backfill fields introduced in the same model version. * + * @example + * ``` + * let change: SavedObjectsModelDataBackfillChange = { + * type: 'data_backfill', + * transform: (document) => { + * document.attributes.someAddedField = 'defaultValue'; + * return { document }; + * }, + * }; + * ``` + * * @remark This type of model change should only be used to backfill newly introduced fields. * Even if no check is performed to ensure that, using such transformations to mutate * existing data of the document can lead to data corruption or inconsistency. diff --git a/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_version.ts b/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_version.ts index 2b8bde3c8e5b6..49107f8ea6190 100644 --- a/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_version.ts +++ b/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_version.ts @@ -19,7 +19,34 @@ import type { SavedObjectsModelChange } from './model_change'; */ export interface SavedObjectsModelVersion { /** - * The list of {@link SavedObjectsModelChange | changes} associated with this version. + * The list of changes associated with this version. + * + * Model version changes are defined via low-level components, allowing to use composition + * to describe the list of changes bound to a given version. Composition also allows to more + * easily merge changes from multiple source when needed. + * + * @example Adding a new indexed field with a default value + * ```ts + * const version1: SavedObjectsModelVersion = { + * changes: [ + * { + * type: 'mappings_addition', + * addedMappings: { + * someNewField: { type: 'text' }, + * }, + * }, + * { + * type: 'data_backfill', + * transform: (doc) => { + * doc.attributes.someNewField = 'some default value'; + * return { document: doc }; + * }, + * }, + * ], + * }; + * ``` + * + * See {@link SavedObjectsModelChange | changes} for more information and examples. */ changes: SavedObjectsModelChange[]; /** @@ -37,9 +64,9 @@ export interface SavedObjectsModelVersion { * @example * ```typescript * const modelVersionMap: SavedObjectsModelVersionMap = { - * '1': modelVersion1, - * '2': modelVersion2, - * '3': modelVersion3, + * 1: modelVersion1, + * 2: modelVersion2, + * 3: modelVersion3, * } * ``` * diff --git a/packages/core/saved-objects/core-saved-objects-server/src/model_version/schemas.ts b/packages/core/saved-objects/core-saved-objects-server/src/model_version/schemas.ts index 6ced7b04b5518..bfcc76de5d4fe 100644 --- a/packages/core/saved-objects/core-saved-objects-server/src/model_version/schemas.ts +++ b/packages/core/saved-objects/core-saved-objects-server/src/model_version/schemas.ts @@ -9,7 +9,7 @@ import type { ObjectType } from '@kbn/config-schema'; /** - * The schemas associated with this model version. + * The validation and conversion schemas associated with this model version. * * @public */ @@ -31,14 +31,6 @@ export interface SavedObjectsModelVersionSchemaDefinitions { forwardCompatibility?: SavedObjectModelVersionForwardCompatibilitySchema; } -/** - * Plain javascript function alternative for {@link SavedObjectModelVersionForwardCompatibilitySchema} - * @public - */ -export type SavedObjectModelVersionForwardCompatibilityFn = ( - attributes: InAttrs -) => OutAttrs; - /** * Schema used when retrieving a document of a higher version to convert them to the older version. * @@ -46,7 +38,7 @@ export type SavedObjectModelVersionForwardCompatibilityFn = ObjectType | SavedObjectModelVersionForwardCompatibilityFn; +> = + | SavedObjectModelVersionForwardCompatibilityObjectSchema + | SavedObjectModelVersionForwardCompatibilityFn; + +/** + * Object-schema (from `@kbn/config-schema`) alternative for {@link SavedObjectModelVersionForwardCompatibilitySchema} + * + * @example + * ```ts + * const versionSchema = schema.object( + * { + * someField: schema.maybe(schema.string()), + * anotherField: schema.maybe(schema.string()), + * }, + * { unknowns: 'ignore' } + * ); + * ``` + * @public + */ +export type SavedObjectModelVersionForwardCompatibilityObjectSchema = ObjectType; + +/** + * Plain javascript function alternative for {@link SavedObjectModelVersionForwardCompatibilitySchema} + * + * @example + * ```ts + * const versionSchema: SavedObjectModelVersionForwardCompatibilityFn = (attributes) => { + * const knownFields = ['someField', 'anotherField']; + * return pick(attributes, knownFields); + * } + * ``` + * @public + */ +export type SavedObjectModelVersionForwardCompatibilityFn = ( + attributes: InAttrs +) => OutAttrs; diff --git a/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts b/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts index b9fa8e6365114..716b31406649c 100644 --- a/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts +++ b/packages/core/saved-objects/core-saved-objects-server/src/saved_objects_type.ts @@ -20,6 +20,8 @@ import type { } from './model_version'; /** + * Definition of a type of savedObject. + * * @public */ export interface SavedObjectsType { @@ -142,9 +144,9 @@ export interface SavedObjectsType { * Model versioning is decoupled from Kibana versioning, and isolated between types. * Model versions are identified by a single numeric value, starting at `1` and without gaps. * - * Please refer to {@link SavedObjectsModelVersion} for details on the API's usages. + * Please refer to {@link SavedObjectsModelVersion} for more details on the model version API. * - * A **valid** versioning would be: + * @example A **valid** versioning would be: * * ```ts * { @@ -158,7 +160,7 @@ export interface SavedObjectsType { * } * ``` * - * A **invalid** versioning would be: + * @example An **invalid** versioning would be: * * ```ts * { @@ -171,8 +173,6 @@ export interface SavedObjectsType { * } * } * ``` - * - * @alpha experimental and subject to change. */ modelVersions?: SavedObjectsModelVersionMap | SavedObjectsModelVersionMapProvider; @@ -184,9 +184,9 @@ export interface SavedObjectsType { * When specified, the type will switch from using the {@link SavedObjectsType.migrations | legacy migration API} * to use the {@link SavedObjectsType.modelVersions | modelVersion API} after the specified version. * - * When opted in, it will no longer be possible to use the legacy migration API after the specified version. + * Once opted in, it will no longer be possible to use the legacy migration API after the specified version. * - * A **valid** usage example would be: + * @example A **valid** usage example would be: * * ```ts * { @@ -203,7 +203,7 @@ export interface SavedObjectsType { * } * ``` * - * An **invalid** usage example would be: + * @example An **invalid** usage example would be: * * ```ts * { @@ -224,8 +224,8 @@ export interface SavedObjectsType { * Please refer to the {@link SavedObjectsType.modelVersions | modelVersion API} for more documentation on * the new API. * - * @remarks All types will be forced to switch to use the new API in a later version. This switch is - * allowing types owners to switch their types before the milestone. + * @remarks All types will be forced to switch to use the new API during `8.10.0`. This switch is + * allowing types owners to switch their types before the milestone (and for testing purposes). */ switchToModelVersionAt?: string; } From 81b9bd2d906ac4db3c156f21a7696764c016e1a6 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Thu, 1 Jun 2023 07:47:37 -0300 Subject: [PATCH 19/31] [Infrastructure UI] Hosts View flaky test - Remove async from describe (#158752) fixes: [#157721](https://github.com/elastic/kibana/issues/157721) ## Summary This PR aims to fix a flaky, my main suspicion is the existence of an async `describe`, that could influence the execution of other tests. The test `describe` itself contained a test that wasn't really relevant for the Host View test suite because it validated the Processes tab summary field titles. I decided to remove it altogether --- .../test/functional/apps/infra/hosts_view.ts | 62 ++++++------------- 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/x-pack/test/functional/apps/infra/hosts_view.ts b/x-pack/test/functional/apps/infra/hosts_view.ts index b2755359144f9..f745bd0e45c08 100644 --- a/x-pack/test/functional/apps/infra/hosts_view.ts +++ b/x-pack/test/functional/apps/infra/hosts_view.ts @@ -146,8 +146,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { security.user.delete('global_hosts_read_privileges_user'), ]); - // Failing: See https://github.com/elastic/kibana/issues/157721 - describe.skip('Hosts View', function () { + describe('Hosts View', function () { this.tags('includeFirefox'); before(async () => { @@ -160,11 +159,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await browser.setWindowSize(1600, 1200); }); - after(() => { - esArchiver.unload('x-pack/test/functional/es_archives/infra/alerts'); - esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'); - esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_hosts_processes'); - browser.removeLocalStorageItem(HOSTS_LINK_LOCAL_STORAGE_KEY); + after(async () => { + await Promise.all([ + esArchiver.unload('x-pack/test/functional/es_archives/infra/alerts'), + esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'), + esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_hosts_processes'), + browser.removeLocalStorageItem(HOSTS_LINK_LOCAL_STORAGE_KEY), + ]); }); it('should be accessible from the Inventory page', async () => { @@ -302,42 +303,19 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.header.waitUntilLoadingHasFinished(); }); - describe('should render processes tab', async () => { - const processTitles = [ - 'Total processes', - 'Running', - 'Sleeping', - 'Dead', - 'Stopped', - 'Idle', - 'Zombie', - 'Unknown', - ]; - - processTitles.forEach((value, index) => { - it(`Render title: ${value}`, async () => { - await pageObjects.infraHostsView.clickProcessesFlyoutTab(); - const processesTitleValue = - await pageObjects.infraHostsView.getProcessesTabContentTitle(index); - const processValue = await processesTitleValue.getVisibleText(); - expect(processValue).to.eql(value); - }); - }); - - it('should render processes total value', async () => { - await pageObjects.infraHostsView.clickProcessesFlyoutTab(); - const processesTotalValue = - await pageObjects.infraHostsView.getProcessesTabContentTotalValue(); - const processValue = await processesTotalValue.getVisibleText(); - expect(processValue).to.eql('313'); - }); + it('should render processes tab and with Total Value summary', async () => { + await pageObjects.infraHostsView.clickProcessesFlyoutTab(); + const processesTotalValue = + await pageObjects.infraHostsView.getProcessesTabContentTotalValue(); + const processValue = await processesTotalValue.getVisibleText(); + expect(processValue).to.eql('313'); + }); - it('should render processes table', async () => { - await pageObjects.infraHostsView.clickProcessesFlyoutTab(); - await pageObjects.infraHostsView.getProcessesTable(); - await pageObjects.infraHostsView.getProcessesTableBody(); - await pageObjects.infraHostsView.clickProcessesTableExpandButton(); - }); + it('should expand processes table row', async () => { + await pageObjects.infraHostsView.clickProcessesFlyoutTab(); + await pageObjects.infraHostsView.getProcessesTable(); + await pageObjects.infraHostsView.getProcessesTableBody(); + await pageObjects.infraHostsView.clickProcessesTableExpandButton(); }); }); From d13f884ec3a4e61fcc23e5594741ec436fa4c4fb Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Thu, 1 Jun 2023 13:12:21 +0200 Subject: [PATCH 20/31] Change kibana.alert.evaluation.threshold unit to microseconds (#158703) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves #156255 Fixes #158204 Partially reverts #154801 [RFC Document](https://docs.google.com/document/d/1-O6-nqOedrjtTF9mHawd_u-vUdXu06KGI8ic5qNeQPQ/edit?usp=sharing) ## Summary This PR changes kibana.alert.evaluation.threshold unit to microseconds in AAD. |Case|Screenshot| |----|---| |Saved value in AAD|![image](https://github.com/elastic/kibana/assets/12370520/9178031b-a187-4b3e-b6ed-6e67f4e708ce)| |Should show correct information in flyout|![image](https://github.com/elastic/kibana/assets/12370520/75ec6664-8e2f-448d-b6d0-dacf01b22ac3)| |Should show correct information on alert details page|![image](https://github.com/elastic/kibana/assets/12370520/4fb4b645-b450-48da-bec9-e7064b26258e)| |Should show correct information in action message|![image](https://github.com/elastic/kibana/assets/12370520/c103266e-25ef-4c25-a0da-c6ecfd0e4c0a)| |Same unit for value and threshold in the alert table|![image](https://github.com/elastic/kibana/assets/12370520/499814bc-9f41-4b94-9b03-18a75a50489f)| ## 🧪 How to test - Generate an APM Latency threshold alert - Check the threshold in - Alert's flyout - Alert's table - Alert details page (summary and chart) - Action generated by this alert --- .../alert_details_app_section/index.tsx | 6 +----- .../register_transaction_duration_rule_type.ts | 2 +- .../components/alerts_flyout/alerts_flyout_body.tsx | 12 ++---------- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/apm/public/components/alerting/ui_components/alert_details_app_section/index.tsx b/x-pack/plugins/apm/public/components/alerting/ui_components/alert_details_app_section/index.tsx index 5632108846e2b..91fa325f4ae7e 100644 --- a/x-pack/plugins/apm/public/components/alerting/ui_components/alert_details_app_section/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/ui_components/alert_details_app_section/index.tsx @@ -21,7 +21,6 @@ import React, { useEffect, useMemo } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { getPaddedAlertTimeRange } from '@kbn/observability-alert-details'; import { EuiCallOut } from '@elastic/eui'; -import { toMicroseconds as toMicrosecondsUtil } from '../../../../../common/utils/formatters'; import { SERVICE_ENVIRONMENT } from '../../../../../common/es_fields/apm'; import { ChartPointerEventContextProvider } from '../../../../context/chart_pointer_event/chart_pointer_event_context'; import { TimeRangeMetadataContextProvider } from '../../../../context/time_range_metadata/time_range_metadata_context'; @@ -37,9 +36,6 @@ import { TRANSACTION_TYPE, } from './types'; -const toMicroseconds = (value?: number) => - value ? toMicrosecondsUtil(value, 'milliseconds') : value; - export function AlertDetailsAppSection({ rule, alert, @@ -69,7 +65,7 @@ export function AlertDetailsAppSection({ ), value: formatAlertEvaluationValue( alert?.fields[ALERT_RULE_TYPE_ID], - toMicroseconds(alert?.fields[ALERT_EVALUATION_THRESHOLD]) + alert?.fields[ALERT_EVALUATION_THRESHOLD] ), }, { diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts index 0ac465261c954..768d7f8a9f781 100644 --- a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts +++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts @@ -280,7 +280,7 @@ export function registerTransactionDurationRuleType({ [TRANSACTION_NAME]: ruleParams.transactionName, [PROCESSOR_EVENT]: ProcessorEvent.transaction, [ALERT_EVALUATION_VALUE]: transactionDuration, - [ALERT_EVALUATION_THRESHOLD]: ruleParams.threshold, + [ALERT_EVALUATION_THRESHOLD]: thresholdMicroseconds, [ALERT_REASON]: reason, ...sourceFields, ...groupByFields, diff --git a/x-pack/plugins/observability/public/components/alerts_flyout/alerts_flyout_body.tsx b/x-pack/plugins/observability/public/components/alerts_flyout/alerts_flyout_body.tsx index 281fed8451ce9..c476f1376d774 100644 --- a/x-pack/plugins/observability/public/components/alerts_flyout/alerts_flyout_body.tsx +++ b/x-pack/plugins/observability/public/components/alerts_flyout/alerts_flyout_body.tsx @@ -30,7 +30,7 @@ import { AlertLifecycleStatusBadge } from '@kbn/alerts-ui-shared'; import moment from 'moment-timezone'; import { useUiSetting } from '@kbn/kibana-react-plugin/public'; import { useKibana } from '../../utils/kibana_react'; -import { asDuration, toMicroseconds } from '../../../common/utils/formatters'; +import { asDuration } from '../../../common/utils/formatters'; import { paths } from '../../config/paths'; import { translations } from '../../config/translations'; import { formatAlertEvaluationValue } from '../../utils/format_alert_evaluation_value'; @@ -42,14 +42,6 @@ interface FlyoutProps { id?: string; } -// For APM Latency threshold rule, threshold is in ms but the duration formatter works with microseconds -const normalizeUnit = (ruleTypeId: string, value?: number) => { - if (ruleTypeId === 'apm.transaction_duration' && value) { - return toMicroseconds(value, 'milliseconds'); - } - return value; -}; - export function AlertsFlyoutBody({ alert, id: pageId }: FlyoutProps) { const { http: { @@ -97,7 +89,7 @@ export function AlertsFlyoutBody({ alert, id: pageId }: FlyoutProps) { title: translations.alertsFlyout.expectedValueLabel, description: formatAlertEvaluationValue( alert.fields[ALERT_RULE_TYPE_ID], - normalizeUnit(alert.fields[ALERT_RULE_TYPE_ID], alert.fields[ALERT_EVALUATION_THRESHOLD]) + alert.fields[ALERT_EVALUATION_THRESHOLD] ), }, { From 2bee02ffd088a2f3fd6a74f0b5efadf43a7085b2 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 1 Jun 2023 14:16:35 +0300 Subject: [PATCH 21/31] [Discover] Enable expanded row view (#158623) ## Summary Part of https://github.com/elastic/kibana/issues/154331 Enables the expanded row view for text based documents for both the legacy and datagrid modes (the legacy was broken) image Note: I am hiding for now the single document view and surrounding document view. I think that we should think about it more and if it makes sense for ESQL. With ESQL if there is no @timestamp I see all my data in the table. If I want to narrow the results I can use where and limit. How should the surrounding documents work for a query with where date field and with llimit? Does it make sense? Possibly not, because with ESQL I can have the surrounding documents view in my main view bu just changing the query. So I am hiding them for now, until we find a good use case for that and decide how we want this to work. ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../public/application/doc/components/doc.tsx | 5 + .../components/layout/discover_documents.tsx | 4 +- .../discover_grid/discover_grid.scss | 8 +- .../discover_grid/discover_grid.tsx | 14 +- .../discover_grid_flyout.test.tsx | 14 ++ .../discover_grid/discover_grid_flyout.tsx | 133 ++++++++++-------- .../doc_table/components/table_row.test.tsx | 12 ++ .../doc_table/components/table_row.tsx | 6 + .../components/table_row_details.tsx | 80 ++++++----- .../doc_table/create_doc_table_embeddable.tsx | 1 + .../doc_table/doc_table_wrapper.tsx | 10 ++ .../embeddable/saved_search_embeddable.tsx | 3 + .../saved_search_embeddable_component.tsx | 14 +- .../public/embeddable/saved_search_grid.tsx | 2 +- .../public/hooks/use_es_doc_search.test.tsx | 35 +++++ .../public/hooks/use_es_doc_search.ts | 13 +- src/plugins/discover/public/plugin.tsx | 35 ++--- .../components/doc_viewer_source/source.tsx | 4 + .../services/doc_views/doc_views_types.ts | 3 + .../apps/discover/group2/_sql_view.ts | 10 +- 20 files changed, 273 insertions(+), 133 deletions(-) diff --git a/src/plugins/discover/public/application/doc/components/doc.tsx b/src/plugins/discover/public/application/doc/components/doc.tsx index a213cfbdd12ad..c5560122c3885 100644 --- a/src/plugins/discover/public/application/doc/components/doc.tsx +++ b/src/plugins/discover/public/application/doc/components/doc.tsx @@ -16,6 +16,7 @@ import { DocViewer } from '../../../services/doc_views/components/doc_viewer'; import { ElasticRequestState } from '../types'; import { useEsDocSearch } from '../../../hooks/use_es_doc_search'; import { useDiscoverServices } from '../../../hooks/use_discover_services'; +import type { DataTableRecord } from '../../../types'; export interface DocProps { /** @@ -38,6 +39,10 @@ export interface DocProps { * Discover main view url */ referrer?: string; + /** + * Records fetched from text based query + */ + textBasedHits?: DataTableRecord[]; } export function Doc(props: DocProps) { diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 3070f447712c5..bf26ffaade95a 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -208,6 +208,7 @@ function DiscoverDocumentsComponent({ isLoading={isDataLoading} searchDescription={savedSearch.description} sharedItemTitle={savedSearch.title} + isPlainRecord={isPlainRecord} onAddColumn={onAddColumn} onFilter={onAddFilter as DocViewFilterFn} onMoveColumn={onMoveColumn} @@ -238,7 +239,7 @@ function DiscoverDocumentsComponent({ sampleSize={sampleSize} searchDescription={savedSearch.description} searchTitle={savedSearch.title} - setExpandedDoc={!isPlainRecord ? setExpandedDoc : undefined} + setExpandedDoc={setExpandedDoc} showTimeCol={showTimeCol} settings={grid} onAddColumn={onAddColumn} @@ -252,6 +253,7 @@ function DiscoverDocumentsComponent({ onUpdateRowHeight={onUpdateRowHeight} isSortEnabled={!isPlainRecord} isPlainRecord={isPlainRecord} + query={query} rowsPerPageState={rowsPerPage} onUpdateRowsPerPage={onUpdateRowsPerPage} onFieldEdited={onFieldEdited} diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid.scss b/src/plugins/discover/public/components/discover_grid/discover_grid.scss index a80f2cd6b5534..18fc15f024fa4 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid.scss +++ b/src/plugins/discover/public/components/discover_grid/discover_grid.scss @@ -15,16 +15,12 @@ padding: 0; } - .dscDiscoverGrid__textLanguageMode .euiDataGridRowCell.euiDataGridRowCell--firstColumn { - padding: $euiSizeXS; - } - .euiDataGridRowCell.euiDataGridRowCell--lastColumn { border-right: none; } - .dscDiscoverGrid__documentsMode .euiDataGridRowCell:first-of-type, - .dscDiscoverGrid__documentsMode .euiDataGrid--headerShade.euiDataGrid--bordersAll .euiDataGridHeaderCell:first-of-type { + .dscDiscoverGrid__table .euiDataGridRowCell:first-of-type, + .dscDiscoverGrid__table .euiDataGrid--headerShade.euiDataGrid--bordersAll .euiDataGridHeaderCell:first-of-type { border-left: none; border-right: none; } diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx index 4f72f9550b1a3..34ddd0c995666 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx @@ -25,7 +25,7 @@ import { } from '@elastic/eui'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { SortOrder } from '@kbn/saved-search-plugin/public'; -import { Filter } from '@kbn/es-query'; +import type { AggregateQuery, Filter, Query } from '@kbn/es-query'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import type { ToastsStart, IUiSettingsClient, HttpStart, CoreStart } from '@kbn/core/public'; import { DataViewFieldEditorStart } from '@kbn/data-view-field-editor-plugin/public'; @@ -191,6 +191,10 @@ export interface DiscoverGridProps { * Filters applied by saved search embeddable */ filters?: Filter[]; + /** + * Query applied by KQL bar or text based editor + */ + query?: Query | AggregateQuery; /** * Saved search id used for links to single doc and surrounding docs in the flyout */ @@ -224,6 +228,7 @@ export const DiscoverGrid = ({ expandedDoc, onAddColumn, filters, + query, savedSearchId, onFilter, onRemoveColumn, @@ -596,11 +601,7 @@ export const DiscoverGrid = ({ data-title={searchTitle} data-description={searchDescription} data-document-number={displayedRows.length} - className={classnames( - className, - 'dscDiscoverGrid__table', - isPlainRecord ? 'dscDiscoverGrid__textLanguageMode' : 'dscDiscoverGrid__documentsMode' - )} + className={classnames(className, 'dscDiscoverGrid__table')} > setExpandedDoc(undefined)} setExpandedDoc={setExpandedDoc} + query={query} /> )} diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.test.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.test.tsx index bdda6d80436c8..22ed742dd3f94 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.test.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { findTestSubject } from '@elastic/eui/lib/test'; import { mountWithIntl } from '@kbn/test-jest-helpers'; +import type { Query, AggregateQuery } from '@kbn/es-query'; import { DiscoverGridFlyout, DiscoverGridFlyoutProps } from './discover_grid_flyout'; import { esHits } from '../../__mocks__/es_hits'; import { createFilterManagerMock } from '@kbn/data-plugin/public/query/filter_manager/filter_manager.mock'; @@ -40,10 +41,12 @@ describe('Discover flyout', function () { dataView, hits, hitIndex, + query, }: { dataView?: DataView; hits?: DataTableRecord[]; hitIndex?: number; + query?: Query | AggregateQuery; }) => { const onClose = jest.fn(); const services = { @@ -71,6 +74,7 @@ describe('Discover flyout', function () { hits: hits || esHits.map((entry: EsHitRecord) => buildDataTableRecord(entry, dataView || dataViewMock)), + query, onAddColumn: jest.fn(), onClose, onFilter: jest.fn(), @@ -192,4 +196,14 @@ describe('Discover flyout', function () { findTestSubject(component, 'docTableDetailsFlyout').simulate('keydown', { key: 'ArrowRight' }); expect(props.setExpandedDoc).not.toHaveBeenCalled(); }); + + it('should not render single/surrounding views for text based', async () => { + const { component } = await mountComponent({ + query: { sql: 'Select * from indexpattern' }, + }); + const singleDocumentView = findTestSubject(component, 'docTableRowAction'); + expect(singleDocumentView.length).toBeFalsy(); + const flyoutTitle = findTestSubject(component, 'docTableRowDetailsTitle'); + expect(flyoutTitle.text()).toBe('Expanded row'); + }); }); diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.tsx index ade63023dd7bc..b2ff52600793f 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid_flyout.tsx @@ -25,16 +25,18 @@ import { EuiHideFor, keys, } from '@elastic/eui'; -import { Filter } from '@kbn/es-query'; +import type { Filter, Query, AggregateQuery } from '@kbn/es-query'; import { DocViewer } from '../../services/doc_views/components/doc_viewer/doc_viewer'; import { DocViewFilterFn } from '../../services/doc_views/doc_views_types'; import { useNavigationProps } from '../../hooks/use_navigation_props'; import { useDiscoverServices } from '../../hooks/use_discover_services'; +import { isTextBasedQuery } from '../../application/main/utils/is_text_based_query'; import type { DataTableRecord } from '../../types'; export interface DiscoverGridFlyoutProps { savedSearchId?: string; filters?: Filter[]; + query?: Query | AggregateQuery; columns: string[]; hit: DataTableRecord; hits?: DataTableRecord[]; @@ -61,6 +63,7 @@ export function DiscoverGridFlyout({ columns, savedSearchId, filters, + query, onFilter, onClose, onRemoveColumn, @@ -68,6 +71,7 @@ export function DiscoverGridFlyout({ setExpandedDoc, }: DiscoverGridFlyoutProps) { const services = useDiscoverServices(); + const isPlainRecord = isTextBasedQuery(query); // Get actual hit with updated highlighted searches const actualHit = useMemo(() => hits?.find(({ id }) => id === hit?.id) || hit, [hit, hits]); const pageCount = useMemo(() => (hits ? hits.length : 0), [hits]); @@ -120,80 +124,88 @@ export function DiscoverGridFlyout({ data-test-subj="docTableRowDetailsTitle" >

- {i18n.translate('discover.grid.tableRow.detailHeading', { - defaultMessage: 'Expanded document', - })} + {isPlainRecord + ? i18n.translate('discover.grid.tableRow.textBasedDetailHeading', { + defaultMessage: 'Expanded row', + }) + : i18n.translate('discover.grid.tableRow.detailHeading', { + defaultMessage: 'Expanded document', + })}

- - - - - {i18n.translate('discover.grid.tableRow.viewText', { - defaultMessage: 'View:', - })} - - - - - - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - - {i18n.translate('discover.grid.tableRow.viewSingleDocumentLinkTextSimple', { - defaultMessage: 'Single document', - })} - - - {dataView.isTimeBased() && dataView.id && ( - + {!isPlainRecord && ( + <> + + + + + {i18n.translate('discover.grid.tableRow.viewText', { + defaultMessage: 'View:', + })} + + + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - {i18n.translate( - 'discover.grid.tableRow.viewSurroundingDocumentsLinkTextSimple', - { - defaultMessage: 'Surrounding documents', - } - )} + {i18n.translate('discover.grid.tableRow.viewSingleDocumentLinkTextSimple', { + defaultMessage: 'Single document', + })} - - - - + {dataView.isTimeBased() && dataView.id && ( + + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} + + {i18n.translate( + 'discover.grid.tableRow.viewSurroundingDocumentsLinkTextSimple', + { + defaultMessage: 'Surrounding documents', + } + )} + + + + + + + )} + )} {activePage !== -1 && ( @@ -236,6 +248,7 @@ export function DiscoverGridFlyout({ }) ); }} + textBasedHits={isPlainRecord ? hits : undefined} /> diff --git a/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx b/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx index 0ada6a3c09ed5..d6a94a5e766f0 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_row.test.tsx @@ -132,5 +132,17 @@ describe('Doc table row component', () => { toggleButton.simulate('click'); expect(findTestSubject(component, 'docTableRowDetailsTitle').exists()).toBeTruthy(); }); + + it('should hide the single/surrounding views for text based languages', () => { + const props = { + ...defaultProps, + isPlainRecord: true, + }; + const component = mountComponent(props); + const toggleButton = findTestSubject(component, 'docTableExpandToggleColumn'); + toggleButton.simulate('click'); + expect(findTestSubject(component, 'docTableRowDetailsTitle').text()).toBe('Expanded row'); + expect(findTestSubject(component, 'docTableRowAction').length).toBeFalsy(); + }); }); }); diff --git a/src/plugins/discover/public/components/doc_table/components/table_row.tsx b/src/plugins/discover/public/components/doc_table/components/table_row.tsx index 34ceaa1d5c5e9..fe1dd59e825b5 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_row.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_row.tsx @@ -31,8 +31,10 @@ export interface TableRowProps { columns: string[]; filter: DocViewFilterFn; filters?: Filter[]; + isPlainRecord?: boolean; savedSearchId?: string; row: DataTableRecord; + rows: DataTableRecord[]; dataView: DataView; useNewFieldsApi: boolean; shouldShowFieldHandler: ShouldShowFieldInTableHandler; @@ -43,10 +45,12 @@ export interface TableRowProps { export const TableRow = ({ filters, + isPlainRecord, columns, filter, savedSearchId, row, + rows, dataView, useNewFieldsApi, shouldShowFieldHandler, @@ -212,6 +216,7 @@ export const TableRow = ({ columns={columns} filters={filters} savedSearchId={savedSearchId} + isPlainRecord={isPlainRecord} > )} diff --git a/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx b/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx index 08ebd3072b17e..1ef01a7094ef9 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx @@ -23,6 +23,7 @@ interface TableRowDetailsProps { dataView: DataView; filters?: Filter[]; savedSearchId?: string; + isPlainRecord?: boolean; } export const TableRowDetails = ({ @@ -35,6 +36,7 @@ export const TableRowDetails = ({ columns, filters, savedSearchId, + isPlainRecord, }: TableRowDetailsProps) => { const { singleDocHref, contextViewHref, onOpenSingleDoc, onOpenContextView } = useNavigationProps( { @@ -58,55 +60,65 @@ export const TableRowDetails = ({

- + {isPlainRecord && ( + + )} + {!isPlainRecord && ( + + )}

- - - - {isTimeBased && ( - /* eslint-disable-next-line @elastic/eui/href-or-on-click */ + {!isPlainRecord && ( + + + + {isTimeBased && ( + /* eslint-disable-next-line @elastic/eui/href-or-on-click */ + + + + )} + + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - )} - - - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - - - - - - + + + + )}
{children}
diff --git a/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx b/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx index d629c6f61f469..e45faec8cbaa1 100644 --- a/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx +++ b/src/plugins/discover/public/components/doc_table/create_doc_table_embeddable.tsx @@ -32,6 +32,7 @@ export function DiscoverDocTableEmbeddable(renderProps: DocTableEmbeddableProps) searchDescription={renderProps.searchDescription} sharedItemTitle={renderProps.sharedItemTitle} isLoading={renderProps.isLoading} + isPlainRecord={renderProps.isPlainRecord} dataTestSubj="embeddedSavedSearchDocTable" DocViewer={DocViewer} /> diff --git a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx index 23558a4979490..b824a70ceb862 100644 --- a/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx +++ b/src/plugins/discover/public/components/doc_table/doc_table_wrapper.tsx @@ -61,6 +61,11 @@ export interface DocTableProps { * Filters applied by embeddalbe */ filters?: Filter[]; + /** + * Flag which identifies if Discover operates + * in text based mode (ESQL) + */ + isPlainRecord?: boolean; /** * Saved search id */ @@ -114,6 +119,7 @@ export const DocTableWrapper = forwardRef( render, columns, filters, + isPlainRecord, savedSearchId, rows, dataView, @@ -187,6 +193,8 @@ export const DocTableWrapper = forwardRef( onAddColumn={onAddColumn} onRemoveColumn={onRemoveColumn} DocViewer={DocViewer} + isPlainRecord={isPlainRecord} + rows={rows} /> )); }, @@ -201,6 +209,8 @@ export const DocTableWrapper = forwardRef( onAddColumn, onRemoveColumn, DocViewer, + isPlainRecord, + rows, ] ); diff --git a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx index 1317916588184..fa0a74f5d0205 100644 --- a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx @@ -556,10 +556,13 @@ export class SavedSearchEmbeddable return; } const useLegacyTable = this.services.uiSettings.get(DOC_TABLE_LEGACY); + const query = this.savedSearch.searchSource.getField('query'); + const props = { savedSearch: this.savedSearch, searchProps, useLegacyTable, + query, }; if (searchProps.services) { ReactDOM.render( diff --git a/src/plugins/discover/public/embeddable/saved_search_embeddable_component.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable_component.tsx index f19dff31b8c0a..03ab602cd760a 100644 --- a/src/plugins/discover/public/embeddable/saved_search_embeddable_component.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable_component.tsx @@ -7,15 +7,17 @@ */ import React from 'react'; - +import { AggregateQuery, Query } from '@kbn/es-query'; import { DiscoverGridEmbeddable, DiscoverGridEmbeddableProps } from './saved_search_grid'; import { DiscoverDocTableEmbeddable } from '../components/doc_table/create_doc_table_embeddable'; import { DocTableEmbeddableProps } from '../components/doc_table/doc_table_embeddable'; +import { isTextBasedQuery } from '../application/main/utils/is_text_based_query'; import { SearchProps } from './saved_search_embeddable'; interface SavedSearchEmbeddableComponentProps { searchProps: SearchProps; useLegacyTable: boolean; + query?: AggregateQuery | Query; } const DiscoverDocTableEmbeddableMemoized = React.memo(DiscoverDocTableEmbeddable); @@ -24,14 +26,22 @@ const DiscoverGridEmbeddableMemoized = React.memo(DiscoverGridEmbeddable); export function SavedSearchEmbeddableComponent({ searchProps, useLegacyTable, + query, }: SavedSearchEmbeddableComponentProps) { if (useLegacyTable) { - return ; + const isPlainRecord = isTextBasedQuery(query); + return ( + + ); } return ( ); diff --git a/src/plugins/discover/public/embeddable/saved_search_grid.tsx b/src/plugins/discover/public/embeddable/saved_search_grid.tsx index 21514a61c87a9..8428d6a488fbc 100644 --- a/src/plugins/discover/public/embeddable/saved_search_grid.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_grid.tsx @@ -29,7 +29,7 @@ export function DiscoverGridEmbeddable(props: DiscoverGridEmbeddableProps) { > diff --git a/src/plugins/discover/public/hooks/use_es_doc_search.test.tsx b/src/plugins/discover/public/hooks/use_es_doc_search.test.tsx index 007512d235657..f095ae8bc3a24 100644 --- a/src/plugins/discover/public/hooks/use_es_doc_search.test.tsx +++ b/src/plugins/discover/public/hooks/use_es_doc_search.test.tsx @@ -286,4 +286,39 @@ describe('Test of helper / hook', () => { buildDataTableRecord(record), ]); }); + + test('useEsDocSearch for text based languages', async () => { + const dataView = { + getComputedFields: () => [], + getIndexPattern: () => index, + }; + const props = { + id: '1', + index: 'index1', + dataView, + textBasedHits: [ + { + id: '1', + raw: { field1: 1, field2: 2 }, + flattened: { field1: 1, field2: 2 }, + }, + ], + } as unknown as DocProps; + + const hook = renderHook((p: DocProps) => useEsDocSearch(p), { + initialProps: props, + wrapper: ({ children }) => ( + {children} + ), + }); + + expect(hook.result.current.slice(0, 2)).toEqual([ + ElasticRequestState.Found, + { + id: '1', + raw: { field1: 1, field2: 2 }, + flattened: { field1: 1, field2: 2 }, + }, + ]); + }); }); diff --git a/src/plugins/discover/public/hooks/use_es_doc_search.ts b/src/plugins/discover/public/hooks/use_es_doc_search.ts index f2a5e3b112371..59538bb62ebe1 100644 --- a/src/plugins/discover/public/hooks/use_es_doc_search.ts +++ b/src/plugins/discover/public/hooks/use_es_doc_search.ts @@ -27,6 +27,7 @@ export function useEsDocSearch({ index, dataView, requestSource, + textBasedHits, }: DocProps): [ElasticRequestState, DataTableRecord | null, () => void] { const [status, setStatus] = useState(ElasticRequestState.Loading); const [hit, setHit] = useState(null); @@ -65,8 +66,16 @@ export function useEsDocSearch({ }, [id, index, dataView, data.search, useNewFieldsApi, requestSource]); useEffect(() => { - requestData(); - }, [requestData]); + if (textBasedHits) { + const selectedHit = textBasedHits?.find((r) => r.id === id); + if (selectedHit) { + setStatus(ElasticRequestState.Found); + setHit(selectedHit); + } + } else { + requestData(); + } + }, [id, requestData, textBasedHits]); return [status, hit, requestData]; } diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 969ec70a104f2..afaaf2f66cd9c 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -262,22 +262,25 @@ export class DiscoverPlugin defaultMessage: 'JSON', }), order: 20, - component: ({ hit, dataView }) => ( - - - - } - > - - - ), + component: ({ hit, dataView, query, textBasedHits }) => { + return ( + + + + } + > + + + ); + }, }); const { diff --git a/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.tsx b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.tsx index 98a242c20ea91..7a28934dab424 100644 --- a/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.tsx +++ b/src/plugins/discover/public/services/doc_views/components/doc_viewer_source/source.tsx @@ -16,6 +16,7 @@ import { DataView } from '@kbn/data-views-plugin/public'; import { useDiscoverServices } from '../../../../hooks/use_discover_services'; import { JSONCodeEditorCommonMemoized } from '../../../../components/json_code_editor/json_code_editor_common'; import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common'; +import type { DataTableRecord } from '../../../../types'; import { useEsDocSearch } from '../../../../hooks/use_es_doc_search'; import { ElasticRequestState } from '../../../../application/doc/types'; import { getHeight } from './get_height'; @@ -24,6 +25,7 @@ interface SourceViewerProps { id: string; index: string; dataView: DataView; + textBasedHits?: DataTableRecord[]; hasLineNumbers: boolean; width?: number; } @@ -40,6 +42,7 @@ export const DocViewerSource = ({ dataView, width, hasLineNumbers, + textBasedHits, }: SourceViewerProps) => { const [editor, setEditor] = useState(); const [editorHeight, setEditorHeight] = useState(); @@ -52,6 +55,7 @@ export const DocViewerSource = ({ index, dataView, requestSource: useNewFieldsApi, + textBasedHits, }); useEffect(() => { diff --git a/src/plugins/discover/public/services/doc_views/doc_views_types.ts b/src/plugins/discover/public/services/doc_views/doc_views_types.ts index 80ee0c724edd1..c91285e144b38 100644 --- a/src/plugins/discover/public/services/doc_views/doc_views_types.ts +++ b/src/plugins/discover/public/services/doc_views/doc_views_types.ts @@ -7,6 +7,7 @@ */ import { DataView, DataViewField } from '@kbn/data-views-plugin/public'; +import type { AggregateQuery, Query } from '@kbn/es-query'; import { DataTableRecord } from '../../types'; import { IgnoredReason } from '../../utils/get_ignored_reason'; @@ -29,6 +30,8 @@ export interface DocViewRenderProps { hit: DataTableRecord; dataView: DataView; columns?: string[]; + query?: Query | AggregateQuery; + textBasedHits?: DataTableRecord[]; filter?: DocViewFilterFn; onAddColumn?: (columnName: string) => void; onRemoveColumn?: (columnName: string) => void; diff --git a/test/functional/apps/discover/group2/_sql_view.ts b/test/functional/apps/discover/group2/_sql_view.ts index 3cc65ba4c3502..e2cfb68cef5b5 100644 --- a/test/functional/apps/discover/group2/_sql_view.ts +++ b/test/functional/apps/discover/group2/_sql_view.ts @@ -77,7 +77,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await testSubjects.exists('unifiedHistogramQueryHits')).to.be(true); expect(await testSubjects.exists('discoverAlertsButton')).to.be(false); expect(await testSubjects.exists('shareTopNavButton')).to.be(true); - expect(await testSubjects.exists('docTableExpandToggleColumn')).to.be(false); + expect(await testSubjects.exists('docTableExpandToggleColumn')).to.be(true); expect(await testSubjects.exists('dataGridColumnSortingButton')).to.be(false); expect(await testSubjects.exists('fieldListFiltersFieldTypeFilterToggle')).to.be(true); await testSubjects.click('field-@message-showDetails'); @@ -97,7 +97,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // here Lens suggests a heatmap so it is rendered expect(await testSubjects.exists('unifiedHistogramChart')).to.be(true); expect(await testSubjects.exists('heatmapChart')).to.be(true); - const cell = await dataGrid.getCellElement(0, 3); + const cell = await dataGrid.getCellElement(0, 4); expect(await cell.getVisibleText()).to.be('2269'); }); @@ -110,7 +110,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await monacoEditor.setCodeEditorValue(testQuery); await testSubjects.click('querySubmitButton'); await PageObjects.header.waitUntilLoadingHasFinished(); - let cell = await dataGrid.getCellElement(0, 3); + let cell = await dataGrid.getCellElement(0, 4); expect(await cell.getVisibleText()).to.be('2269'); await PageObjects.timePicker.setAbsoluteRange( 'Sep 19, 2015 @ 06:31:44.000', @@ -120,7 +120,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await testSubjects.exists('discoverNoResults')).to.be(true); await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.header.waitUntilLoadingHasFinished(); - cell = await dataGrid.getCellElement(0, 3); + cell = await dataGrid.getCellElement(0, 4); expect(await cell.getVisibleText()).to.be('2269'); }); @@ -135,7 +135,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.click('querySubmitButton'); await PageObjects.header.waitUntilLoadingHasFinished(); - const cell = await dataGrid.getCellElement(0, 3); + const cell = await dataGrid.getCellElement(0, 4); expect(await cell.getVisibleText()).to.be('2269'); }); }); From 36ae6c8e62dcfc03d411f16b11e0b8a8f835f6a4 Mon Sep 17 00:00:00 2001 From: Sander Philipse <94373878+sphilipse@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:42:54 +0200 Subject: [PATCH 22/31] [Serverless Search] Fix curl icon (#158814) ## Summary This fixes a broken cURL icon. --- .../public/application/components/languages/curl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/serverless_search/public/application/components/languages/curl.ts b/x-pack/plugins/serverless_search/public/application/components/languages/curl.ts index 0df5deff5a11f..41c18a9470dcb 100644 --- a/x-pack/plugins/serverless_search/public/application/components/languages/curl.ts +++ b/x-pack/plugins/serverless_search/public/application/components/languages/curl.ts @@ -24,7 +24,7 @@ export const curlDefinition: LanguageDefinition = { configureClient: ({ apiKey, url }) => `export ES_URL="${url}" export API_KEY="${apiKey}"`, docLink: docLinks.apiIntro, - iconType: 'cURL.svg', + iconType: 'curl.svg', id: Languages.CURL, ingestData: `curl -X POST "\$\{ES_URL\}/_bulk?pretty" \\ -H "Authorization: ApiKey "\$\{API_KEY\}"" \\ From 0f02b9e968f43bdae1c26c0149f47e6266e85827 Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Thu, 1 Jun 2023 07:56:51 -0400 Subject: [PATCH 23/31] [Response Ops][Alerting] Adding null checks when iterating through index template list (#158742) ## Summary When updating common component templates during AAD resource installation, we occassionally run into errors where the index templates using the common component template has a total field limit that is less than the new total number of fields with the updated component template. When this occurs, we query the ES index template API to get the list of index templates in order to check their `composed_of` field to see if they reference the specific component template and act accordingly. In theory, `composed_of` is (and is typed as) a required array. In practice, it seems that this field can be missing from the response. Since we're doing a `.includes` check on this array, this can lead to null dereference errors that can halt alerts as data resource installation. This PR adds a check to make sure the `composed_of` field exists before using it. ## To Verify 1. Run Kibana 8.6 locally and create a metric threshold rule & detection rule that generates alerts. Make sure the alert index templates for these rule types have been created and the rule runs successfully. 2. Update to Kibana 8.7. Make sure the rules run successfully and generate alerts. Create a data view with no component templates. To do this, go to `Stack Management > Index Management > Index Templates` and click `Create template`. Fill in a name and index pattern (`test*` is fine) and make sure the `Create data stream` switch is checked. Click through all the remaining options without setting anything else. Use `GET /_index_template/` to verify that this index template has no `composed_of` field 3. Update to this branch. All alert resources should be installed successfully and there should be no errors on startup. --- ...reate_or_update_component_template.test.ts | 106 ++++++++++++++++++ .../create_or_update_component_template.ts | 12 +- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts index 1083807a29c9f..3a1d490afe9d6 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts @@ -189,6 +189,112 @@ describe('createOrUpdateComponentTemplate', () => { }); }); + it(`should update index template field limit and retry if putTemplate throws error with field limit error when there are malformed index templates`, async () => { + clusterClient.cluster.putComponentTemplate.mockRejectedValueOnce( + new EsErrors.ResponseError( + elasticsearchClientMock.createApiResponse({ + statusCode: 400, + body: { + error: { + root_cause: [ + { + type: 'illegal_argument_exception', + reason: + 'updating component template [.alerts-ecs-mappings] results in invalid composable template [.alerts-security.alerts-default-index-template] after templates are merged', + }, + ], + type: 'illegal_argument_exception', + reason: + 'updating component template [.alerts-ecs-mappings] results in invalid composable template [.alerts-security.alerts-default-index-template] after templates are merged', + caused_by: { + type: 'illegal_argument_exception', + reason: + 'composable template [.alerts-security.alerts-default-index-template] template after composition with component templates [.alerts-ecs-mappings, .alerts-security.alerts-mappings, .alerts-technical-mappings] is invalid', + caused_by: { + type: 'illegal_argument_exception', + reason: + 'invalid composite mappings for [.alerts-security.alerts-default-index-template]', + caused_by: { + type: 'illegal_argument_exception', + reason: 'Limit of total fields [1900] has been exceeded', + }, + }, + }, + }, + }, + }) + ) + ); + const existingIndexTemplate = { + name: 'test-template', + index_template: { + index_patterns: ['test*'], + composed_of: ['test-mappings'], + template: { + settings: { + auto_expand_replicas: '0-1', + hidden: true, + 'index.lifecycle': { + name: '.alerts-ilm-policy', + rollover_alias: `.alerts-empty-default`, + }, + 'index.mapping.total_fields.limit': 1800, + }, + mappings: { + dynamic: false, + }, + }, + }, + }; + + clusterClient.indices.getIndexTemplate.mockResolvedValueOnce({ + index_templates: [ + existingIndexTemplate, + { + name: 'lyndon', + // @ts-expect-error + index_template: { + index_patterns: ['intel*'], + }, + }, + { + name: 'sample_ds', + // @ts-expect-error + index_template: { + index_patterns: ['sample_ds-*'], + data_stream: { + hidden: false, + allow_custom_routing: false, + }, + }, + }, + ], + }); + + await createOrUpdateComponentTemplate({ + logger, + esClient: clusterClient, + template: ComponentTemplate, + totalFieldsLimit: 2500, + }); + + expect(clusterClient.cluster.putComponentTemplate).toHaveBeenCalledTimes(2); + expect(clusterClient.indices.putIndexTemplate).toHaveBeenCalledTimes(1); + expect(clusterClient.indices.putIndexTemplate).toHaveBeenCalledWith({ + name: existingIndexTemplate.name, + body: { + ...existingIndexTemplate.index_template, + template: { + ...existingIndexTemplate.index_template.template, + settings: { + ...existingIndexTemplate.index_template.template?.settings, + 'index.mapping.total_fields.limit': 2500, + }, + }, + }, + }); + }); + it(`should retry getIndexTemplate and putIndexTemplate on transient ES errors`, async () => { clusterClient.cluster.putComponentTemplate.mockRejectedValueOnce( new EsErrors.ResponseError( diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts index 97cdef833adbc..2a241b4b839ad 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts @@ -32,8 +32,16 @@ const getIndexTemplatesUsingComponentTemplate = async ( { logger } ); const indexTemplatesUsingComponentTemplate = (indexTemplates ?? []).filter( - (indexTemplate: IndicesGetIndexTemplateIndexTemplateItem) => - indexTemplate.index_template.composed_of.includes(componentTemplateName) + (indexTemplate: IndicesGetIndexTemplateIndexTemplateItem) => { + if ( + indexTemplate && + indexTemplate.index_template && + indexTemplate.index_template.composed_of + ) { + return indexTemplate.index_template.composed_of.includes(componentTemplateName); + } + return false; + } ); await asyncForEach( indexTemplatesUsingComponentTemplate, From b2f48f2d5486ee01d11caa48bcd864e75d801fe1 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Thu, 1 Jun 2023 14:10:59 +0200 Subject: [PATCH 24/31] [spacetime] Improve `scripts/build_api_docs` stats output speed. (#157129) The existing `build_api_docs` script takes about ~10m to run and generate the API docs. That's not too bad for the daily CI task that generates the docs. However, even if you're just interested in getting some stats on a single plugin/package it runs the full script. We often have to run this script locally to check the stats in detail to improve JSDoc and missing exports which is quite cumbersome if it takes this long to run after each code change. This PR updates the script in the following way: If both the options `--stats` and `--plugin` (with a single plugin/package) are set, it will not generate a TS project for the whole Kibana codebase but just the code related to that plugin/package. API docs will then not be written to avoid inconsistencies and just the stats will be logged. Depending on the size of the package/plugin this can reduce the time needed to run the script down to a few seconds. --- .../kbn-docs-utils/src/build_api_docs_cli.ts | 182 +++++++++++++++--- packages/kbn-docs-utils/src/find_plugins.ts | 22 ++- packages/kbn-docs-utils/tsconfig.json | 1 + 3 files changed, 175 insertions(+), 30 deletions(-) diff --git a/packages/kbn-docs-utils/src/build_api_docs_cli.ts b/packages/kbn-docs-utils/src/build_api_docs_cli.ts index c5db0718927ca..c771ebd743b40 100644 --- a/packages/kbn-docs-utils/src/build_api_docs_cli.ts +++ b/packages/kbn-docs-utils/src/build_api_docs_cli.ts @@ -10,11 +10,14 @@ import Fs from 'fs'; import Fsp from 'fs/promises'; import Path from 'path'; +import apm, { type Transaction } from 'elastic-apm-node'; +import { Project } from 'ts-morph'; + import { run } from '@kbn/dev-cli-runner'; import { createFlagError } from '@kbn/dev-cli-errors'; import { CiStatsReporter } from '@kbn/ci-stats-reporter'; import { REPO_ROOT } from '@kbn/repo-info'; -import { Project } from 'ts-morph'; +import { initApm } from '@kbn/apm-config-loader'; import { writePluginDocs } from './mdx/write_plugin_mdx_docs'; import { ApiDeclaration, ApiStats, PluginMetaInfo } from './types'; @@ -35,9 +38,23 @@ function isStringArray(arr: unknown | string[]): arr is string[] { return Array.isArray(arr) && arr.every((p) => typeof p === 'string'); } +const rootDir = Path.join(__dirname, '../../..'); +initApm(process.argv, rootDir, false, 'build_api_docs_cli'); + +async function endTransactionWithFailure(transaction: Transaction | null) { + if (transaction !== null) { + transaction.setOutcome('failure'); + transaction.end(); + await apm.flush(); + } +} + export function runBuildApiDocsCli() { run( async ({ log, flags }) => { + const transaction = apm.startTransaction('build-api-docs', 'kibana-cli'); + const spanSetup = transaction?.startSpan('build_api_docs.setup', 'setup'); + const collectReferences = flags.references as boolean; const stats = flags.stats && typeof flags.stats === 'string' ? [flags.stats] : flags.stats; const pluginFilter = @@ -46,6 +63,7 @@ export function runBuildApiDocsCli() { : (flags.plugin as string[] | undefined); if (pluginFilter && !isStringArray(pluginFilter)) { + await endTransactionWithFailure(transaction); throw createFlagError('expected --plugin must only contain strings'); } @@ -55,6 +73,7 @@ export function runBuildApiDocsCli() { stats.find((s) => s !== 'any' && s !== 'comments' && s !== 'exports')) || (stats && !isStringArray(stats)) ) { + await endTransactionWithFailure(transaction); throw createFlagError( 'expected --stats must only contain `any`, `comments` and/or `exports`' ); @@ -62,14 +81,45 @@ export function runBuildApiDocsCli() { const outputFolder = Path.resolve(REPO_ROOT, 'api_docs'); + spanSetup?.end(); + const spanInitialDocIds = transaction?.startSpan('build_api_docs.initialDocIds', 'setup'); + const initialDocIds = !pluginFilter && Fs.existsSync(outputFolder) ? await getAllDocFileIds(outputFolder) : undefined; - const project = getTsProject(REPO_ROOT); + spanInitialDocIds?.end(); + const spanPlugins = transaction?.startSpan('build_api_docs.findPlugins', 'setup'); + + const plugins = findPlugins(stats && pluginFilter ? pluginFilter : undefined); + + if (stats && Array.isArray(pluginFilter) && pluginFilter.length !== plugins.length) { + await endTransactionWithFailure(transaction); + throw createFlagError('expected --plugin was not found'); + } + + spanPlugins?.end(); + + const spanPathsByPackage = transaction?.startSpan( + 'build_api_docs.getPathsByPackage', + 'setup' + ); + + const pathsByPlugin = await getPathsByPackage(plugins); + + spanPathsByPackage?.end(); + + const spanProject = transaction?.startSpan('build_api_docs.getTsProject', 'setup'); + + const project = getTsProject( + REPO_ROOT, + stats && pluginFilter && plugins.length === 1 ? plugins[0].directory : undefined + ); - const plugins = findPlugins(); + spanProject?.end(); + + const spanFolders = transaction?.startSpan('build_api_docs.check-folders', 'setup'); // if the output folder already exists, and we don't have a plugin filter, delete all the files in the output folder if (Fs.existsSync(outputFolder) && !pluginFilter) { @@ -81,6 +131,9 @@ export function runBuildApiDocsCli() { await Fsp.mkdir(outputFolder, { recursive: true }); } + spanFolders?.end(); + const spanPluginApiMap = transaction?.startSpan('build_api_docs.getPluginApiMap', 'setup'); + const { pluginApiMap, missingApiItems, @@ -89,12 +142,23 @@ export function runBuildApiDocsCli() { adoptionTrackedAPIs, } = getPluginApiMap(project, plugins, log, { collectReferences, pluginFilter }); + spanPluginApiMap?.end(); + const reporter = CiStatsReporter.fromEnv(log); - const pathsByPlugin = await getPathsByPackage(plugins); const allPluginStats: { [key: string]: PluginMetaInfo & ApiStats & EslintDisableCounts } = {}; for (const plugin of plugins) { const id = plugin.id; + + if (stats && pluginFilter && !pluginFilter.includes(plugin.id)) { + continue; + } + + const spanApiStatsForPlugin = transaction?.startSpan( + `build_api_docs.collectApiStatsForPlugin-${id}`, + 'stats' + ); + const pluginApi = pluginApiMap[id]; const paths = pathsByPlugin.get(plugin) ?? []; @@ -110,9 +174,20 @@ export function runBuildApiDocsCli() { description: plugin.manifest.description, isPlugin: plugin.isPlugin, }; + + spanApiStatsForPlugin?.end(); } - await writePluginDirectoryDoc(outputFolder, pluginApiMap, allPluginStats, log); + if (!stats) { + const spanWritePluginDirectoryDoc = transaction?.startSpan( + 'build_api_docs.writePluginDirectoryDoc', + 'write' + ); + + await writePluginDirectoryDoc(outputFolder, pluginApiMap, allPluginStats, log); + + spanWritePluginDirectoryDoc?.end(); + } for (const plugin of plugins) { // Note that the filtering is done here, and not above because the entire public plugin API has to @@ -127,6 +202,11 @@ export function runBuildApiDocsCli() { const pluginStats = allPluginStats[id]; const pluginTeam = plugin.manifest.owner.name; + const spanMetrics = transaction?.startSpan( + `build_api_docs.collectApiStatsForPlugin-${id}`, + 'stats' + ); + reporter.metrics([ { id, @@ -283,20 +363,56 @@ export function runBuildApiDocsCli() { } } - if (pluginStats.apiCount > 0) { - log.info(`Writing public API doc for plugin ${pluginApi.id}.`); - await writePluginDocs(outputFolder, { doc: pluginApi, plugin, pluginStats, log }); - } else { - log.info(`Plugin ${pluginApi.id} has no public API.`); + spanMetrics?.end(); + + if (!stats) { + if (pluginStats.apiCount > 0) { + log.info(`Writing public API doc for plugin ${pluginApi.id}.`); + + const spanWritePluginDocs = transaction?.startSpan( + 'build_api_docs.writePluginDocs', + 'write' + ); + + await writePluginDocs(outputFolder, { doc: pluginApi, plugin, pluginStats, log }); + + spanWritePluginDocs?.end(); + } else { + log.info(`Plugin ${pluginApi.id} has no public API.`); + } + + const spanWriteDeprecationDocByPlugin = transaction?.startSpan( + 'build_api_docs.writeDeprecationDocByPlugin', + 'write' + ); + + await writeDeprecationDocByPlugin(outputFolder, referencedDeprecations, log); + + spanWriteDeprecationDocByPlugin?.end(); + + const spanWriteDeprecationDueByTeam = transaction?.startSpan( + 'build_api_docs.writeDeprecationDueByTeam', + 'write' + ); + + await writeDeprecationDueByTeam(outputFolder, referencedDeprecations, plugins, log); + + spanWriteDeprecationDueByTeam?.end(); + + const spanWriteDeprecationDocByApi = transaction?.startSpan( + 'build_api_docs.writeDeprecationDocByApi', + 'write' + ); + + await writeDeprecationDocByApi( + outputFolder, + referencedDeprecations, + unreferencedDeprecations, + log + ); + + spanWriteDeprecationDocByApi?.end(); } - await writeDeprecationDocByPlugin(outputFolder, referencedDeprecations, log); - await writeDeprecationDueByTeam(outputFolder, referencedDeprecations, plugins, log); - await writeDeprecationDocByApi( - outputFolder, - referencedDeprecations, - unreferencedDeprecations, - log - ); } if (Object.values(pathsOutsideScopes).length > 0) { @@ -307,6 +423,8 @@ export function runBuildApiDocsCli() { if (initialDocIds) { await trimDeletedDocsFromNav(log, initialDocIds, outputFolder); } + + transaction?.end(); }, { log: { @@ -316,26 +434,36 @@ export function runBuildApiDocsCli() { string: ['plugin', 'stats'], boolean: ['references'], help: ` - --plugin Optionally, run for only a specific plugin - --stats Optionally print API stats. Must be one or more of: any, comments or exports. - --references Collect references for API items + --plugin Optionally, run for only a specific plugin + --stats Optionally print API stats. Must be one or more of: any, comments or exports. + In combination with a single plugin filter this option will skip writing any + API docs as a tradeoff to just produce the stats output more quickly. + --references Collect references for API items `, }, } ); } -function getTsProject(repoPath: string) { - const xpackTsConfig = `${repoPath}/tsconfig.json`; +function getTsProject(repoPath: string, overridePath?: string) { + const xpackTsConfig = !overridePath + ? `${repoPath}/tsconfig.json` + : `${overridePath}/tsconfig.json`; + const project = new Project({ tsConfigFilePath: xpackTsConfig, // We'll use the files added below instead. skipAddingFilesFromTsConfig: true, }); - project.addSourceFilesAtPaths([`${repoPath}/x-pack/plugins/**/*.ts`, '!**/*.d.ts']); - project.addSourceFilesAtPaths([`${repoPath}/x-pack/packages/**/*.ts`, '!**/*.d.ts']); - project.addSourceFilesAtPaths([`${repoPath}/src/plugins/**/*.ts`, '!**/*.d.ts']); - project.addSourceFilesAtPaths([`${repoPath}/packages/**/*.ts`, '!**/*.d.ts']); + + if (!overridePath) { + project.addSourceFilesAtPaths([`${repoPath}/x-pack/plugins/**/*.ts`, '!**/*.d.ts']); + project.addSourceFilesAtPaths([`${repoPath}/x-pack/packages/**/*.ts`, '!**/*.d.ts']); + project.addSourceFilesAtPaths([`${repoPath}/src/plugins/**/*.ts`, '!**/*.d.ts']); + project.addSourceFilesAtPaths([`${repoPath}/packages/**/*.ts`, '!**/*.d.ts']); + } else { + project.addSourceFilesAtPaths([`${overridePath}/**/*.ts`, '!**/*.d.ts']); + } project.resolveSourceFileDependencies(); return project; } diff --git a/packages/kbn-docs-utils/src/find_plugins.ts b/packages/kbn-docs-utils/src/find_plugins.ts index 30a63b55172e1..c77816ba3b6c8 100644 --- a/packages/kbn-docs-utils/src/find_plugins.ts +++ b/packages/kbn-docs-utils/src/find_plugins.ts @@ -52,7 +52,7 @@ function toPluginOrPackage(pkg: Package): PluginOrPackage { }; } -export function findPlugins(): PluginOrPackage[] { +export function findPlugins(pluginOrPackageFilter?: string[]): PluginOrPackage[] { const packages = getPackages(REPO_ROOT); const plugins = packages.filter( getPluginPackagesFilter({ @@ -66,14 +66,30 @@ export function findPlugins(): PluginOrPackage[] { throw new Error('unable to find @kbn/core'); } - return [...[core, ...plugins].map(toPluginOrPackage), ...findPackages()]; + if (!pluginOrPackageFilter) { + return [...[core, ...plugins].map(toPluginOrPackage), ...findPackages()]; + } else { + return [ + ...plugins + .filter((p) => pluginOrPackageFilter.includes(p.manifest.plugin.id)) + .map(toPluginOrPackage), + ...findPackages(pluginOrPackageFilter), + ]; + } } /** * Helper to find packages. */ -export function findPackages(): PluginOrPackage[] { +export function findPackages(packageFilter?: string[]): PluginOrPackage[] { return getPackages(REPO_ROOT) .filter((p) => !p.isPlugin()) + .filter((p) => { + if (!Array.isArray(packageFilter)) { + return true; + } else { + return packageFilter.includes(p.manifest.id); + } + }) .map(toPluginOrPackage); } diff --git a/packages/kbn-docs-utils/tsconfig.json b/packages/kbn-docs-utils/tsconfig.json index fa23110abcb1f..9116acc8dcbc5 100644 --- a/packages/kbn-docs-utils/tsconfig.json +++ b/packages/kbn-docs-utils/tsconfig.json @@ -23,5 +23,6 @@ "@kbn/std", "@kbn/get-repo-files", "@kbn/repo-packages", + "@kbn/apm-config-loader", ] } From ab4181aaca625a0a7999829ba2c0c24857000852 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 1 Jun 2023 08:28:53 -0400 Subject: [PATCH 25/31] skip failing test suite (#157721) --- x-pack/test/functional/apps/infra/hosts_view.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/infra/hosts_view.ts b/x-pack/test/functional/apps/infra/hosts_view.ts index f745bd0e45c08..d80971abfead7 100644 --- a/x-pack/test/functional/apps/infra/hosts_view.ts +++ b/x-pack/test/functional/apps/infra/hosts_view.ts @@ -146,7 +146,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { security.user.delete('global_hosts_read_privileges_user'), ]); - describe('Hosts View', function () { + // Failing: See https://github.com/elastic/kibana/issues/157721 + describe.skip('Hosts View', function () { this.tags('includeFirefox'); before(async () => { From 06c337f903a5b310f8a21a66065b186bbbc9642e Mon Sep 17 00:00:00 2001 From: Gerard Soldevila Date: Thu, 1 Jun 2023 14:47:40 +0200 Subject: [PATCH 26/31] Refactor KibanaMigrator, improve readability, maintainability and UT (#155693) Addresses the following feedback: https://github.com/elastic/kibana/pull/154151#discussion_r1158470566 Similar to what has been done for ZDT, the goal of this PR is to extract the logic of the `runV2Migration()` from the `KibanaMigrator` into a separate file. The PR also fixes some incomplete / incorrect UTs and adds a few missing ones. --- .../src/retry_call_cluster.ts | 2 +- .../index.ts | 1 + .../src/constants.ts | 116 +++++ .../src/kibana_migrator.test.ts | 483 +++++------------- .../src/kibana_migrator.ts | 157 ++---- .../src/kibana_migrator_constants.ts | 107 ---- .../src/kibana_migrator_utils.fixtures.ts | 37 -- .../src/kibana_migrator_utils.test.ts | 6 +- .../src/model/model.test.ts | 6 +- .../src/model/model.ts | 2 +- .../src/run_resilient_migrator.fixtures.ts | 59 +++ .../src/run_resilient_migrator.test.ts | 156 ++++++ .../src/run_resilient_migrator.ts | 40 +- .../src/run_v2_migration.test.ts | 273 ++++++++++ .../src/run_v2_migration.ts | 153 ++++++ .../src/saved_objects_service.ts | 2 + .../active_delete_multiple_instances.test.ts | 2 + .../group3/dot_kibana_split.test.ts | 2 + .../migrations/kibana_migrator_test_kit.ts | 45 +- 19 files changed, 988 insertions(+), 661 deletions(-) create mode 100644 packages/core/saved-objects/core-saved-objects-base-server-internal/src/constants.ts create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.fixtures.ts create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.test.ts create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.test.ts create mode 100644 packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.ts diff --git a/packages/core/elasticsearch/core-elasticsearch-server-internal/src/retry_call_cluster.ts b/packages/core/elasticsearch/core-elasticsearch-server-internal/src/retry_call_cluster.ts index b3d5c69cec155..e20639cf4f405 100644 --- a/packages/core/elasticsearch/core-elasticsearch-server-internal/src/retry_call_cluster.ts +++ b/packages/core/elasticsearch/core-elasticsearch-server-internal/src/retry_call_cluster.ts @@ -48,7 +48,7 @@ export const retryCallCluster = >(apiCaller: () => T) * Retries the provided Elasticsearch API call when an error such as * `AuthenticationException` `NoConnections`, `ConnectionFault`, * `ServiceUnavailable` or `RequestTimeout` are encountered. The API call will - * be retried once a second, indefinitely, until a successful response or a + * be retried once every `delay` millis, indefinitely, until a successful response or a * different error is received. * * @example diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/index.ts index 5d14a4f9e4cbb..eea0966433f02 100644 --- a/packages/core/saved-objects/core-saved-objects-base-server-internal/index.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/index.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +export { DEFAULT_INDEX_TYPES_MAP } from './src/constants'; export { LEGACY_URL_ALIAS_TYPE, type LegacyUrlAlias } from './src/legacy_alias'; export { getProperty, diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/src/constants.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/constants.ts new file mode 100644 index 0000000000000..c4a3018fdfb37 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/constants.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { IndexTypesMap } from './mappings'; + +/** + * This map holds the default breakdown of SO types per index (pre 8.8.0) + */ +export const DEFAULT_INDEX_TYPES_MAP: IndexTypesMap = { + '.kibana_task_manager': ['task'], + '.kibana': [ + 'action', + 'action_task_params', + 'alert', + 'api_key_pending_invalidation', + 'apm-indices', + 'apm-server-schema', + 'apm-service-group', + 'apm-telemetry', + 'app_search_telemetry', + 'application_usage_daily', + 'application_usage_totals', + 'book', + 'canvas-element', + 'canvas-workpad', + 'canvas-workpad-template', + 'cases', + 'cases-comments', + 'cases-configure', + 'cases-connector-mappings', + 'cases-telemetry', + 'cases-user-actions', + 'config', + 'config-global', + 'connector_token', + 'core-usage-stats', + 'csp-rule-template', + 'dashboard', + 'endpoint:user-artifact-manifest', + 'enterprise_search_telemetry', + 'epm-packages', + 'epm-packages-assets', + 'event_loop_delays_daily', + 'exception-list', + 'exception-list-agnostic', + 'file', + 'file-upload-usage-collection-telemetry', + 'fileShare', + 'fleet-fleet-server-host', + 'fleet-message-signing-keys', + 'fleet-preconfiguration-deletion-record', + 'fleet-proxy', + 'graph-workspace', + 'guided-onboarding-guide-state', + 'guided-onboarding-plugin-state', + 'index-pattern', + 'infrastructure-monitoring-log-view', + 'infrastructure-ui-source', + 'ingest-agent-policies', + 'ingest-download-sources', + 'ingest-outputs', + 'ingest-package-policies', + 'ingest_manager_settings', + 'inventory-view', + 'kql-telemetry', + 'legacy-url-alias', + 'lens', + 'lens-ui-telemetry', + 'map', + 'metrics-explorer-view', + 'ml-job', + 'ml-module', + 'ml-trained-model', + 'monitoring-telemetry', + 'osquery-manager-usage-metric', + 'osquery-pack', + 'osquery-pack-asset', + 'osquery-saved-query', + 'query', + 'rules-settings', + 'sample-data-telemetry', + 'search', + 'search-session', + 'search-telemetry', + 'searchableList', + 'security-rule', + 'security-solution-signals-migration', + 'siem-detection-engine-rule-actions', + 'siem-ui-timeline', + 'siem-ui-timeline-note', + 'siem-ui-timeline-pinned-event', + 'slo', + 'space', + 'spaces-usage-stats', + 'synthetics-monitor', + 'synthetics-param', + 'synthetics-privates-locations', + 'tag', + 'telemetry', + 'todo', + 'ui-metric', + 'upgrade-assistant-ml-upgrade-operation', + 'upgrade-assistant-reindex-operation', + 'uptime-dynamic-settings', + 'uptime-synthetics-api-key', + 'url', + 'usage-counters', + 'visualization', + 'workplace_search_telemetry', + ], +}; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.test.ts index f9537a584881e..284215ef74b45 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.test.ts @@ -7,34 +7,59 @@ */ import { take } from 'rxjs/operators'; -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; - import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import type { SavedObjectsType } from '@kbn/core-saved-objects-server'; -import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; -import { type KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator'; +import { + type MigrationResult, + SavedObjectTypeRegistry, +} from '@kbn/core-saved-objects-base-server-internal'; +import { KibanaMigrator } from './kibana_migrator'; import { DocumentMigrator } from './document_migrator'; import { ByteSizeValue } from '@kbn/config-schema'; import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; import { lastValueFrom } from 'rxjs'; -import * as runResilientMigratorModule from './run_resilient_migrator'; -import { runResilientMigrator } from './run_resilient_migrator'; - -const mappingsResponseWithoutIndexTypesMap: estypes.IndicesGetMappingResponse = { - '.kibana_8.7.0_001': { - mappings: { - _meta: { - migrationMappingPropertyHashes: { - references: '7997cf5a56cc02bdc9c93361bde732b0', - // ... - }, - // we do not add a `indexTypesMap` - // simulating a Kibana < 8.8.0 that does not have one yet - }, - }, +import { runV2Migration } from './run_v2_migration'; +import { runZeroDowntimeMigration } from './zdt'; + +const V2_SUCCESSFUL_MIGRATION_RESULT: MigrationResult[] = [ + { + sourceIndex: '.my_index_pre8.2.3_001', + destIndex: '.my_index_8.2.3_001', + elapsedMs: 14, + status: 'migrated', }, -}; +]; + +const ZDT_SUCCESSFUL_MIGRATION_RESULT: MigrationResult[] = [ + { + sourceIndex: '.my_index_8.8.0_001', + destIndex: '.my_index_8.8.1_001', + elapsedMs: 14, + status: 'migrated', + }, + { + destIndex: '.other_index_8.8.0_001', + elapsedMs: 128, + status: 'patched', + }, +]; + +jest.mock('./run_v2_migration', () => { + return { + runV2Migration: jest.fn( + (): Promise => Promise.resolve(V2_SUCCESSFUL_MIGRATION_RESULT) + ), + }; +}); + +jest.mock('./zdt', () => { + return { + runZeroDowntimeMigration: jest.fn( + (): Promise => Promise.resolve(ZDT_SUCCESSFUL_MIGRATION_RESULT) + ), + }; +}); const createRegistry = (types: Array>) => { const registry = new SavedObjectTypeRegistry(); @@ -51,10 +76,15 @@ const createRegistry = (types: Array>) => { return registry; }; +const mockRunV2Migration = runV2Migration as jest.MockedFunction; +const mockRunZeroDowntimeMigration = runZeroDowntimeMigration as jest.MockedFunction< + typeof runZeroDowntimeMigration +>; + describe('KibanaMigrator', () => { beforeEach(() => { - jest.restoreAllMocks(); - jest.spyOn(runResilientMigratorModule, 'runResilientMigrator'); + mockRunV2Migration.mockClear(); + mockRunZeroDowntimeMigration.mockClear(); }); describe('getActiveMappings', () => { it('returns full index mappings w/ core properties', () => { @@ -68,7 +98,7 @@ describe('KibanaMigrator', () => { }, { name: 'bmap', - indexPattern: '.other-index', + indexPattern: '.other_index', mappings: { properties: { field: { type: 'text' } }, }, @@ -90,6 +120,7 @@ describe('KibanaMigrator', () => { ); }); + // TODO check if it applies it('calls documentMigrator.migrate', () => { const options = mockOptions(); const kibanaMigrator = new KibanaMigrator(options); @@ -102,88 +133,57 @@ describe('KibanaMigrator', () => { }); describe('runMigrations', () => { - it('throws if prepareMigrations is not called first', async () => { + it("calls runV2Migration with the right params when the migration algorithm is 'v2'", async () => { const options = mockOptions(); const migrator = new KibanaMigrator(options); + migrator.prepareMigrations(); + const res = await migrator.runMigrations(); - await expect(migrator.runMigrations()).rejects.toThrowError( - 'Migrations are not ready. Make sure prepareMigrations is called first.' + expect(runV2Migration).toHaveBeenCalledTimes(1); + expect(runZeroDowntimeMigration).not.toHaveBeenCalled(); + expect(runV2Migration).toHaveBeenCalledWith( + expect.objectContaining({ + kibanaVersion: '8.2.3', + kibanaIndexPrefix: '.my_index', + migrationConfig: options.soMigrationsConfig, + waitForMigrationCompletion: false, + }) ); + expect(res).toEqual(V2_SUCCESSFUL_MIGRATION_RESULT); }); - it('only runs migrations once if called multiple times', async () => { - const successfulRun: typeof runResilientMigrator = ({ indexPrefix }) => - Promise.resolve({ - sourceIndex: indexPrefix, - destIndex: indexPrefix, - elapsedMs: 28, - status: 'migrated', - }); - const mockRunResilientMigrator = runResilientMigrator as jest.MockedFunction< - typeof runResilientMigrator - >; - - mockRunResilientMigrator.mockImplementationOnce(successfulRun); - mockRunResilientMigrator.mockImplementationOnce(successfulRun); - mockRunResilientMigrator.mockImplementationOnce(successfulRun); - mockRunResilientMigrator.mockImplementationOnce(successfulRun); - const options = mockOptions(); - options.client.indices.get.mockResponse({}, { statusCode: 200 }); - options.client.indices.getMapping.mockResponse(mappingsResponseWithoutIndexTypesMap, { - statusCode: 200, - }); + it("calls runZeroDowntimeMigration with the right params when the migration algorithm is 'zdt'", async () => { + const options = mockOptions('zdt'); + const migrator = new KibanaMigrator(options); + migrator.prepareMigrations(); + const res = await migrator.runMigrations(); - options.client.cluster.getSettings.mockResponse( - { - transient: {}, - persistent: {}, - }, - { statusCode: 404 } + expect(runZeroDowntimeMigration).toHaveBeenCalledTimes(1); + expect(runV2Migration).not.toHaveBeenCalled(); + expect(runZeroDowntimeMigration).toHaveBeenCalledWith( + expect.objectContaining({ + kibanaVersion: '8.2.3', + kibanaIndexPrefix: '.my_index', + migrationConfig: options.soMigrationsConfig, + }) ); - const migrator = new KibanaMigrator(options); + expect(res).toEqual(ZDT_SUCCESSFUL_MIGRATION_RESULT); + }); + it('only runs migrations once if called multiple times', async () => { + const options = mockOptions(); + const migrator = new KibanaMigrator(options); migrator.prepareMigrations(); await migrator.runMigrations(); await migrator.runMigrations(); await migrator.runMigrations(); // indices.get is called twice during a single migration - expect(runResilientMigrator).toHaveBeenCalledTimes(4); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 1, - expect.objectContaining({ - indexPrefix: '.my-index', - mustRelocateDocuments: true, - }) - ); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 2, - expect.objectContaining({ - indexPrefix: '.other-index', - mustRelocateDocuments: true, - }) - ); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 3, - expect.objectContaining({ - indexPrefix: '.my-task-index', - mustRelocateDocuments: false, - }) - ); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 4, - expect.objectContaining({ - indexPrefix: '.my-complementary-index', - mustRelocateDocuments: true, - }) - ); + expect(runV2Migration).toHaveBeenCalledTimes(1); }); - it('emits results on getMigratorResult$()', async () => { - const options = mockV2MigrationOptions(); - options.client.indices.getMapping.mockResponse(mappingsResponseWithoutIndexTypesMap, { - statusCode: 200, - }); + it('emits v2 results on getMigratorResult$()', async () => { + const options = mockOptions(); const migrator = new KibanaMigrator(options); const migratorStatus = lastValueFrom(migrator.getStatus$().pipe(take(3))); migrator.prepareMigrations(); @@ -191,294 +191,70 @@ describe('KibanaMigrator', () => { const { status, result } = await migratorStatus; expect(status).toEqual('completed'); - expect(result![0]).toMatchObject({ - destIndex: '.my-index_8.2.3_001', - sourceIndex: '.my-index_pre8.2.3_001', - elapsedMs: expect.any(Number), - status: 'migrated', - }); - expect(result![1]).toMatchObject({ - destIndex: '.other-index_8.2.3_001', - elapsedMs: expect.any(Number), - status: 'patched', - }); + expect(result).toEqual(V2_SUCCESSFUL_MIGRATION_RESULT); }); - it('rejects when the migration state machine terminates in a FATAL state', async () => { - const options = mockV2MigrationOptions(); - options.client.indices.get.mockResponse( - { - '.my-index_8.2.4_001': { - aliases: { - '.my-index': {}, - '.my-index_8.2.4': {}, - }, - mappings: { properties: {}, _meta: { migrationMappingPropertyHashes: {} } }, - settings: {}, - }, - }, - { statusCode: 200 } - ); - options.client.indices.getMapping.mockResponse(mappingsResponseWithoutIndexTypesMap, { - statusCode: 200, - }); + it('emits zdt results on getMigratorResult$()', async () => { + const options = mockOptions('zdt'); const migrator = new KibanaMigrator(options); + const migratorStatus = lastValueFrom(migrator.getStatus$().pipe(take(3))); migrator.prepareMigrations(); - return expect(migrator.runMigrations()).rejects.toMatchInlineSnapshot( - `[Error: Unable to complete saved object migrations for the [.my-index] index: The .my-index alias is pointing to a newer version of Kibana: v8.2.4]` - ); - }); + await migrator.runMigrations(); - it('rejects when an unexpected exception occurs in an action', async () => { - const options = mockV2MigrationOptions(); - options.client.tasks.get.mockResponse({ - completed: true, - error: { type: 'elasticsearch_exception', reason: 'task failed with an error' }, - task: { description: 'task description' } as any, - }); - options.client.indices.getMapping.mockResponse(mappingsResponseWithoutIndexTypesMap, { - statusCode: 200, - }); + const { status, result } = await migratorStatus; + expect(status).toEqual('completed'); + expect(result).toEqual(ZDT_SUCCESSFUL_MIGRATION_RESULT); + }); + it('rejects when the v2 migrator algorithm rejects', async () => { + const options = mockOptions(); const migrator = new KibanaMigrator(options); + + const fatal = new Error( + `Unable to complete saved object migrations for the [${options.kibanaIndex}] index: Something went horribly wrong` + ); + mockRunV2Migration.mockRejectedValueOnce(fatal); + migrator.prepareMigrations(); - await expect(migrator.runMigrations()).rejects.toMatchInlineSnapshot(` - [Error: Unable to complete saved object migrations for the [.my-index] index. Error: Reindex failed with the following error: - {"_tag":"Some","value":{"type":"elasticsearch_exception","reason":"task failed with an error"}}] - `); - expect(loggingSystemMock.collect(options.logger).error[0][0]).toMatchInlineSnapshot(` - [Error: Reindex failed with the following error: - {"_tag":"Some","value":{"type":"elasticsearch_exception","reason":"task failed with an error"}}] - `); + expect(migrator.runMigrations()).rejects.toEqual(fatal); }); - describe('for V2 migrations', () => { - describe('where some SO types must be relocated', () => { - it('runs successfully', async () => { - const options = mockV2MigrationOptions(); - options.client.indices.getMapping.mockResponse(mappingsResponseWithoutIndexTypesMap, { - statusCode: 200, - }); - - const migrator = new KibanaMigrator(options); - migrator.prepareMigrations(); - const results = await migrator.runMigrations(); + it('rejects when the zdt migrator algorithm rejects', async () => { + const options = mockOptions('zdt'); + const migrator = new KibanaMigrator(options); - expect(results.length).toEqual(4); - expect(results[0]).toEqual( - expect.objectContaining({ - sourceIndex: '.my-index_pre8.2.3_001', - destIndex: '.my-index_8.2.3_001', - elapsedMs: expect.any(Number), - status: 'migrated', - }) - ); - expect(results[1]).toEqual( - expect.objectContaining({ - destIndex: '.other-index_8.2.3_001', - elapsedMs: expect.any(Number), - status: 'patched', - }) - ); - expect(results[2]).toEqual( - expect.objectContaining({ - destIndex: '.my-task-index_8.2.3_001', - elapsedMs: expect.any(Number), - status: 'patched', - }) - ); - expect(results[3]).toEqual( - expect.objectContaining({ - destIndex: '.my-complementary-index_8.2.3_001', - elapsedMs: expect.any(Number), - status: 'patched', - }) - ); + const fatal = new Error( + `Unable to complete saved object migrations for the [${options.kibanaIndex}] index: Something went terribly wrong` + ); + mockRunZeroDowntimeMigration.mockRejectedValueOnce(fatal); - expect(runResilientMigrator).toHaveBeenCalledTimes(4); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 1, - expect.objectContaining({ - kibanaVersion: '8.2.3', - indexPrefix: '.my-index', - indexTypesMap: { - '.my-index': ['testtype', 'testtype3'], - '.other-index': ['testtype2'], - '.my-task-index': ['testtasktype'], - }, - targetMappings: expect.objectContaining({ - properties: expect.objectContaining({ - testtype: expect.anything(), - testtype3: expect.anything(), - }), - }), - readyToReindex: expect.objectContaining({ - promise: expect.anything(), - resolve: expect.anything(), - reject: expect.anything(), - }), - mustRelocateDocuments: true, - doneReindexing: expect.objectContaining({ - promise: expect.anything(), - resolve: expect.anything(), - reject: expect.anything(), - }), - }) - ); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 2, - expect.objectContaining({ - kibanaVersion: '8.2.3', - indexPrefix: '.other-index', - indexTypesMap: { - '.my-index': ['testtype', 'testtype3'], - '.other-index': ['testtype2'], - '.my-task-index': ['testtasktype'], - }, - targetMappings: expect.objectContaining({ - properties: expect.objectContaining({ - testtype2: expect.anything(), - }), - }), - readyToReindex: expect.objectContaining({ - promise: expect.anything(), - resolve: expect.anything(), - reject: expect.anything(), - }), - mustRelocateDocuments: true, - doneReindexing: expect.objectContaining({ - promise: expect.anything(), - resolve: expect.anything(), - reject: expect.anything(), - }), - }) - ); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 3, - expect.objectContaining({ - kibanaVersion: '8.2.3', - indexPrefix: '.my-task-index', - indexTypesMap: { - '.my-index': ['testtype', 'testtype3'], - '.other-index': ['testtype2'], - '.my-task-index': ['testtasktype'], - }, - targetMappings: expect.objectContaining({ - properties: expect.objectContaining({ - testtasktype: expect.anything(), - }), - }), - // this migrator is NOT involved in any relocation, - // thus, it must not synchronize with other migrators - mustRelocateDocuments: false, - readyToReindex: undefined, - doneReindexing: undefined, - }) - ); - expect(runResilientMigrator).toHaveBeenNthCalledWith( - 4, - expect.objectContaining({ - kibanaVersion: '8.2.3', - indexPrefix: '.my-complementary-index', - indexTypesMap: { - '.my-index': ['testtype', 'testtype3'], - '.other-index': ['testtype2'], - '.my-task-index': ['testtasktype'], - }, - targetMappings: expect.objectContaining({ - properties: expect.not.objectContaining({ - // this index does no longer have any types associated to it - testtype: expect.anything(), - testtype2: expect.anything(), - testtype3: expect.anything(), - testtasktype: expect.anything(), - }), - }), - mustRelocateDocuments: true, - doneReindexing: expect.objectContaining({ - promise: expect.anything(), - resolve: expect.anything(), - reject: expect.anything(), - }), - }) - ); - }); - }); + migrator.prepareMigrations(); + expect(migrator.runMigrations()).rejects.toEqual(fatal); }); }); }); -type MockedOptions = KibanaMigratorOptions & { - client: ReturnType; -}; - -const mockV2MigrationOptions = () => { - const options = mockOptions(); - options.client.cluster.getSettings.mockResponse( - { - transient: {}, - persistent: {}, - }, - { statusCode: 200 } - ); - - options.client.indices.get.mockResponse( - { - '.my-index': { - aliases: { '.kibana': {} }, - mappings: { properties: {} }, - settings: {}, - }, - }, - { statusCode: 200 } - ); - options.client.indices.addBlock.mockResponse({ - acknowledged: true, - shards_acknowledged: true, - indices: [], - }); - options.client.reindex.mockResponse({ - taskId: 'reindex_task_id', - } as estypes.ReindexResponse); - options.client.tasks.get.mockResponse({ - completed: true, - error: undefined, - failures: [], - task: { description: 'task description' } as any, - } as estypes.TasksGetResponse); - - options.client.search.mockResponse({ hits: { hits: [] } } as any); - - options.client.openPointInTime.mockResponse({ id: 'pit_id' }); - - options.client.closePointInTime.mockResponse({ - succeeded: true, - } as estypes.ClosePointInTimeResponse); - - return options; -}; - -const mockOptions = () => { +const mockOptions = (algorithm: 'v2' | 'zdt' = 'v2') => { const mockedClient = elasticsearchClientMock.createElasticsearchClient(); (mockedClient as any).child = jest.fn().mockImplementation(() => mockedClient); - const options: MockedOptions = { + return { logger: loggingSystemMock.create().get(), kibanaVersion: '8.2.3', waitForMigrationCompletion: false, defaultIndexTypesMap: { - '.my-index': ['testtype', 'testtype2'], - '.my-task-index': ['testtasktype'], + '.my_index': ['testtype', 'testtype2'], + '.task_index': ['testtasktype'], // this index no longer has any types registered in typeRegistry // but we still need a migrator for it, so that 'testtype3' documents // are moved over to their new index (.my_index) - '.my-complementary-index': ['testtype3'], + '.my_complementary_index': ['testtype3'], }, typeRegistry: createRegistry([ // typeRegistry depicts an updated index map: - // .my-index: ['testtype', 'testtype3'], - // .my-other-index: ['testtype2'], - // .my-task-index': ['testtasktype'], + // .my_index: ['testtype', 'testtype3'], + // .other_index: ['testtype2'], + // .task_index': ['testtasktype'], { name: 'testtype', hidden: false, @@ -494,8 +270,8 @@ const mockOptions = () => { name: 'testtype2', hidden: false, namespaceType: 'single', - // We are moving 'testtype2' from '.my-index' to '.other-index' - indexPattern: '.other-index', + // We are moving 'testtype2' from '.my_index' to '.other_index' + indexPattern: '.other_index', mappings: { properties: { name: { type: 'keyword' }, @@ -507,7 +283,7 @@ const mockOptions = () => { name: 'testtasktype', hidden: false, namespaceType: 'single', - indexPattern: '.my-task-index', + indexPattern: '.task_index', mappings: { properties: { name: { type: 'keyword' }, @@ -516,7 +292,7 @@ const mockOptions = () => { migrations: {}, }, { - // We are moving 'testtype3' from '.my-complementary-index' to '.my-index' + // We are moving 'testtype3' from '.my_complementary_index' to '.my_index' name: 'testtype3', hidden: false, namespaceType: 'single', @@ -528,9 +304,9 @@ const mockOptions = () => { migrations: {}, }, ]), - kibanaIndex: '.my-index', + kibanaIndex: '.my_index', soMigrationsConfig: { - algorithm: 'v2', + algorithm, batchSize: 20, maxBatchSizeBytes: ByteSizeValue.parse('20mb'), maxReadBatchSizeBytes: new ByteSizeValue(536870888), @@ -547,5 +323,4 @@ const mockOptions = () => { docLinks: docLinksServiceMock.createSetupContract(), nodeRoles: { backgroundTasks: true, ui: true, migrator: true }, }; - return options; }; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.ts index f731b964ab6c7..ac50e60027e2d 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator.ts @@ -12,14 +12,12 @@ */ import { BehaviorSubject } from 'rxjs'; -import Semver from 'semver'; import type { NodeRoles } from '@kbn/core-node-server'; import type { Logger } from '@kbn/logging'; import type { DocLinksServiceStart } from '@kbn/core-doc-links-server'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { type SavedObjectUnsanitizedDoc, - type SavedObjectsRawDoc, type ISavedObjectTypeRegistry, } from '@kbn/core-saved-objects-server'; import { @@ -33,26 +31,22 @@ import { type MigrationResult, type IndexTypesMap, } from '@kbn/core-saved-objects-base-server-internal'; -import { getIndicesInvolvedInRelocation } from './kibana_migrator_utils'; import { buildActiveMappings, buildTypesMappings } from './core'; import { DocumentMigrator } from './document_migrator'; -import { createIndexMap } from './core/build_index_map'; -import { runResilientMigrator } from './run_resilient_migrator'; -import { migrateRawDocsSafely } from './core/migrate_raw_docs'; import { runZeroDowntimeMigration } from './zdt'; -import { createMultiPromiseDefer, indexMapToIndexTypesMap } from './kibana_migrator_utils'; -import { ALLOWED_CONVERT_VERSION, DEFAULT_INDEX_TYPES_MAP } from './kibana_migrator_constants'; +import { ALLOWED_CONVERT_VERSION } from './kibana_migrator_constants'; +import { runV2Migration } from './run_v2_migration'; export interface KibanaMigratorOptions { client: ElasticsearchClient; typeRegistry: ISavedObjectTypeRegistry; + defaultIndexTypesMap: IndexTypesMap; soMigrationsConfig: SavedObjectsMigrationConfigType; kibanaIndex: string; kibanaVersion: string; logger: Logger; docLinks: DocLinksServiceStart; waitForMigrationCompletion: boolean; - defaultIndexTypesMap?: IndexTypesMap; nodeRoles: NodeRoles; } @@ -66,6 +60,7 @@ export class KibanaMigrator implements IKibanaMigrator { private readonly log: Logger; private readonly mappingProperties: SavedObjectsTypeMappingDefinitions; private readonly typeRegistry: ISavedObjectTypeRegistry; + private readonly defaultIndexTypesMap: IndexTypesMap; private readonly serializer: SavedObjectsSerializer; private migrationResult?: Promise; private readonly status$ = new BehaviorSubject({ @@ -75,7 +70,6 @@ export class KibanaMigrator implements IKibanaMigrator { private readonly soMigrationsConfig: SavedObjectsMigrationConfigType; private readonly docLinks: DocLinksServiceStart; private readonly waitForMigrationCompletion: boolean; - private readonly defaultIndexTypesMap: IndexTypesMap; private readonly nodeRoles: NodeRoles; public readonly kibanaVersion: string; @@ -86,11 +80,11 @@ export class KibanaMigrator implements IKibanaMigrator { client, typeRegistry, kibanaIndex, + defaultIndexTypesMap, soMigrationsConfig, kibanaVersion, logger, docLinks, - defaultIndexTypesMap = DEFAULT_INDEX_TYPES_MAP, waitForMigrationCompletion, nodeRoles, }: KibanaMigratorOptions) { @@ -98,6 +92,7 @@ export class KibanaMigrator implements IKibanaMigrator { this.kibanaIndex = kibanaIndex; this.soMigrationsConfig = soMigrationsConfig; this.typeRegistry = typeRegistry; + this.defaultIndexTypesMap = defaultIndexTypesMap; this.serializer = new SavedObjectsSerializer(this.typeRegistry); this.mappingProperties = buildTypesMappings(this.typeRegistry.getAllTypes()); this.log = logger; @@ -114,7 +109,6 @@ export class KibanaMigrator implements IKibanaMigrator { // operation so we cache the result this.activeMappings = buildActiveMappings(this.mappingProperties); this.docLinks = docLinks; - this.defaultIndexTypesMap = defaultIndexTypesMap; } public runMigrations({ rerun = false }: { rerun?: boolean } = {}): Promise { @@ -144,122 +138,37 @@ export class KibanaMigrator implements IKibanaMigrator { return this.status$.asObservable(); } - private async runMigrationsInternal(): Promise { + private runMigrationsInternal(): Promise { const migrationAlgorithm = this.soMigrationsConfig.algorithm; if (migrationAlgorithm === 'zdt') { - return await this.runMigrationZdt(); + return runZeroDowntimeMigration({ + kibanaVersion: this.kibanaVersion, + kibanaIndexPrefix: this.kibanaIndex, + typeRegistry: this.typeRegistry, + logger: this.log, + documentMigrator: this.documentMigrator, + migrationConfig: this.soMigrationsConfig, + docLinks: this.docLinks, + serializer: this.serializer, + elasticsearchClient: this.client, + nodeRoles: this.nodeRoles, + }); } else { - return await this.runMigrationV2(); - } - } - - private runMigrationZdt(): Promise { - return runZeroDowntimeMigration({ - kibanaVersion: this.kibanaVersion, - kibanaIndexPrefix: this.kibanaIndex, - typeRegistry: this.typeRegistry, - logger: this.log, - documentMigrator: this.documentMigrator, - migrationConfig: this.soMigrationsConfig, - docLinks: this.docLinks, - serializer: this.serializer, - elasticsearchClient: this.client, - nodeRoles: this.nodeRoles, - }); - } - - private async runMigrationV2(): Promise { - const indexMap = createIndexMap({ - kibanaIndexName: this.kibanaIndex, - indexMap: this.mappingProperties, - registry: this.typeRegistry, - }); - - this.log.debug('Applying registered migrations for the following saved object types:'); - Object.entries(this.documentMigrator.getMigrationVersion()) - .sort(([t1, v1], [t2, v2]) => { - return Semver.compare(v1, v2); - }) - .forEach(([type, migrationVersion]) => { - this.log.debug(`migrationVersion: ${migrationVersion} saved object type: ${type}`); + return runV2Migration({ + kibanaVersion: this.kibanaVersion, + kibanaIndexPrefix: this.kibanaIndex, + typeRegistry: this.typeRegistry, + defaultIndexTypesMap: this.defaultIndexTypesMap, + logger: this.log, + documentMigrator: this.documentMigrator, + migrationConfig: this.soMigrationsConfig, + docLinks: this.docLinks, + serializer: this.serializer, + elasticsearchClient: this.client, + mappingProperties: this.mappingProperties, + waitForMigrationCompletion: this.waitForMigrationCompletion, }); - - // build a indexTypesMap from the info present in tye typeRegistry, e.g.: - // { - // '.kibana': ['typeA', 'typeB', ...] - // '.kibana_task_manager': ['task', ...] - // '.kibana_cases': ['typeC', 'typeD', ...] - // ... - // } - const indexTypesMap = indexMapToIndexTypesMap(indexMap); - - // compare indexTypesMap with the one present (or not) in the .kibana index meta - // and check if some SO types have been moved to different indices - const indicesWithMovingTypes = await getIndicesInvolvedInRelocation({ - mainIndex: this.kibanaIndex, - client: this.client, - indexTypesMap, - logger: this.log, - defaultIndexTypesMap: this.defaultIndexTypesMap, - }); - - // we create 2 synchronization objects (2 synchronization points) for each of the - // migrators involved in relocations, aka each of the migrators that will: - // A) reindex some documents TO other indices - // B) receive some documents FROM other indices - // C) both - const readyToReindexDefers = createMultiPromiseDefer(indicesWithMovingTypes); - const doneReindexingDefers = createMultiPromiseDefer(indicesWithMovingTypes); - - // build a list of all migrators that must be started - const migratorIndices = new Set(Object.keys(indexMap)); - // indices involved in a relocation might no longer be present in current mappings - // but if their SOs must be relocated to another index, we still need a migrator to do the job - indicesWithMovingTypes.forEach((index) => migratorIndices.add(index)); - - const migrators = Array.from(migratorIndices).map((indexName, i) => { - return { - migrate: (): Promise => { - const readyToReindex = readyToReindexDefers[indexName]; - const doneReindexing = doneReindexingDefers[indexName]; - // check if this migrator's index is involved in some document redistribution - const mustRelocateDocuments = !!readyToReindex; - - return runResilientMigrator({ - client: this.client, - kibanaVersion: this.kibanaVersion, - mustRelocateDocuments, - indexTypesMap, - waitForMigrationCompletion: this.waitForMigrationCompletion, - // a migrator's index might no longer have any associated types to it - targetMappings: buildActiveMappings(indexMap[indexName]?.typeMappings ?? {}), - logger: this.log, - preMigrationScript: indexMap[indexName]?.script, - readyToReindex, - doneReindexing, - transformRawDocs: (rawDocs: SavedObjectsRawDoc[]) => - migrateRawDocsSafely({ - serializer: this.serializer, - migrateDoc: this.documentMigrator.migrateAndConvert, - rawDocs, - }), - coreMigrationVersionPerType: this.documentMigrator.getMigrationVersion({ - includeDeferred: false, - migrationType: 'core', - }), - migrationVersionPerType: this.documentMigrator.getMigrationVersion({ - includeDeferred: false, - }), - indexPrefix: indexName, - migrationsConfig: this.soMigrationsConfig, - typeRegistry: this.typeRegistry, - docLinks: this.docLinks, - }); - }, - }; - }); - - return Promise.all(migrators.map((migrator) => migrator.migrate())); + } } public getActiveMappings(): IndexMapping { diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_constants.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_constants.ts index e18abed5caca7..7a104108c2ecb 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_constants.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_constants.ts @@ -6,8 +6,6 @@ * Side Public License, v 1. */ -import type { IndexTypesMap } from '@kbn/core-saved-objects-base-server-internal'; - export enum TypeStatus { Added = 'added', Removed = 'removed', @@ -24,108 +22,3 @@ export interface TypeStatusDetails { // ensure plugins don't try to convert SO namespaceTypes after 8.0.0 // see https://github.com/elastic/kibana/issues/147344 export const ALLOWED_CONVERT_VERSION = '8.0.0'; - -export const DEFAULT_INDEX_TYPES_MAP: IndexTypesMap = { - '.kibana_task_manager': ['task'], - '.kibana': [ - 'action', - 'action_task_params', - 'alert', - 'api_key_pending_invalidation', - 'apm-indices', - 'apm-server-schema', - 'apm-service-group', - 'apm-telemetry', - 'app_search_telemetry', - 'application_usage_daily', - 'application_usage_totals', - 'book', - 'canvas-element', - 'canvas-workpad', - 'canvas-workpad-template', - 'cases', - 'cases-comments', - 'cases-configure', - 'cases-connector-mappings', - 'cases-telemetry', - 'cases-user-actions', - 'config', - 'config-global', - 'connector_token', - 'core-usage-stats', - 'csp-rule-template', - 'dashboard', - 'endpoint:user-artifact', - 'endpoint:user-artifact-manifest', - 'enterprise_search_telemetry', - 'epm-packages', - 'epm-packages-assets', - 'event_loop_delays_daily', - 'exception-list', - 'exception-list-agnostic', - 'file', - 'file-upload-usage-collection-telemetry', - 'fileShare', - 'fleet-fleet-server-host', - 'fleet-message-signing-keys', - 'fleet-preconfiguration-deletion-record', - 'fleet-proxy', - 'graph-workspace', - 'guided-onboarding-guide-state', - 'guided-onboarding-plugin-state', - 'index-pattern', - 'infrastructure-monitoring-log-view', - 'infrastructure-ui-source', - 'ingest-agent-policies', - 'ingest-download-sources', - 'ingest-outputs', - 'ingest-package-policies', - 'ingest_manager_settings', - 'inventory-view', - 'kql-telemetry', - 'legacy-url-alias', - 'lens', - 'lens-ui-telemetry', - 'map', - 'metrics-explorer-view', - 'ml-job', - 'ml-module', - 'ml-trained-model', - 'monitoring-telemetry', - 'osquery-manager-usage-metric', - 'osquery-pack', - 'osquery-pack-asset', - 'osquery-saved-query', - 'query', - 'rules-settings', - 'sample-data-telemetry', - 'search', - 'search-session', - 'search-telemetry', - 'searchableList', - 'security-rule', - 'security-solution-signals-migration', - 'siem-detection-engine-rule-actions', - 'siem-ui-timeline', - 'siem-ui-timeline-note', - 'siem-ui-timeline-pinned-event', - 'slo', - 'space', - 'spaces-usage-stats', - 'synthetics-monitor', - 'synthetics-param', - 'synthetics-privates-locations', - 'tag', - 'telemetry', - 'todo', - 'ui-metric', - 'upgrade-assistant-ml-upgrade-operation', - 'upgrade-assistant-reindex-operation', - 'uptime-dynamic-settings', - 'uptime-synthetics-api-key', - 'url', - 'usage-counters', - 'visualization', - 'workplace_search_telemetry', - ], -}; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.fixtures.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.fixtures.ts index 802167d733fb5..9100f489bef42 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.fixtures.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.fixtures.ts @@ -3147,43 +3147,6 @@ export const INDEX_MAP_BEFORE_SPLIT: IndexMap = { }, }, }, - 'endpoint:user-artifact': { - properties: { - identifier: { - type: 'keyword', - }, - compressionAlgorithm: { - type: 'keyword', - index: false, - }, - encryptionAlgorithm: { - type: 'keyword', - index: false, - }, - encodedSha256: { - type: 'keyword', - }, - encodedSize: { - type: 'long', - index: false, - }, - decodedSha256: { - type: 'keyword', - index: false, - }, - decodedSize: { - type: 'long', - index: false, - }, - created: { - type: 'date', - index: false, - }, - body: { - type: 'binary', - }, - }, - }, 'endpoint:user-artifact-manifest': { properties: { created: { diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.test.ts index 0698904c45d30..02eb3dcdaadc1 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.test.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/kibana_migrator_utils.test.ts @@ -9,10 +9,12 @@ import { errors } from '@elastic/elasticsearch'; import type { IndicesGetMappingResponse } from '@elastic/elasticsearch/lib/api/types'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import type { IndexTypesMap } from '@kbn/core-saved-objects-base-server-internal'; +import { + DEFAULT_INDEX_TYPES_MAP, + type IndexTypesMap, +} from '@kbn/core-saved-objects-base-server-internal'; import { MAIN_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; import { loggerMock } from '@kbn/logging-mocks'; -import { DEFAULT_INDEX_TYPES_MAP } from './kibana_migrator_constants'; import { calculateTypeStatuses, createMultiPromiseDefer, 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 590ecd7b41c23..6390edd9b04cb 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 @@ -10,7 +10,10 @@ import { chain } from 'lodash'; import * as Either from 'fp-ts/lib/Either'; import * as Option from 'fp-ts/lib/Option'; import type { SavedObjectsRawDoc } from '@kbn/core-saved-objects-server'; -import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; +import { + DEFAULT_INDEX_TYPES_MAP, + type IndexMapping, +} from '@kbn/core-saved-objects-base-server-internal'; import type { BaseState, CalculateExcludeFiltersState, @@ -60,7 +63,6 @@ import type { ResponseType } from '../next'; import { createInitialProgress } from './progress'; import { model } from './model'; import type { BulkIndexOperationTuple, BulkOperation } from './create_batches'; -import { DEFAULT_INDEX_TYPES_MAP } from '../kibana_migrator_constants'; describe('migrations v2 model', () => { const indexMapping: IndexMapping = { 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 5d652f86c51f5..915fe58f6e448 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 @@ -124,7 +124,7 @@ export const model = (currentState: State, resW: ResponseType): const laterVersionAlias = hasLaterVersionAlias(stateP.kibanaVersion, aliases); if ( - // `.kibana_` alias exists, and refers to a later version of Kibana + // a `.kibana_` alias exist, which refers to a later version of Kibana // e.g. `.kibana_8.7.0` exists, and current stack version is 8.6.1 // see https://github.com/elastic/kibana/issues/155136 laterVersionAlias diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.fixtures.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.fixtures.ts new file mode 100644 index 0000000000000..c7a70296f35ba --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.fixtures.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 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 { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; +import type { SavedObjectsType } from '@kbn/core-saved-objects-server'; + +export const createRegistry = (types: Array>) => { + const registry = new SavedObjectTypeRegistry(); + types.forEach((type) => + registry.registerType({ + name: 'unknown', + hidden: false, + namespaceType: 'single', + mappings: { + properties: { + name: { type: 'keyword' }, + }, + }, + migrations: {}, + ...type, + }) + ); + return registry; +}; + +export const indexTypesMapMock = { + '.my_index': ['testtype', 'testtype2'], + '.task_index': ['testtasktype'], + '.complementary_index': ['testtype3'], +}; + +export const savedObjectTypeRegistryMock = createRegistry([ + // typeRegistry depicts an updated index map: + // .my_index: ['testtype', 'testtype3'], + // .other_index: ['testtype2'], + // .task_index': ['testtasktype'], + { + name: 'testtype', + migrations: { '8.2.3': jest.fn().mockImplementation((doc) => doc) }, + }, + { + name: 'testtype2', + // We are moving 'testtype2' from '.my_index' to '.other_index' + indexPattern: '.other_index', + }, + { + name: 'testtasktype', + indexPattern: '.task_index', + }, + { + // We are moving 'testtype3' from '.complementary_index' to '.my_index' + name: 'testtype3', + }, +]); diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.test.ts new file mode 100644 index 0000000000000..280b8fd08f6cf --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.test.ts @@ -0,0 +1,156 @@ +/* + * Copyright 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 buffer from 'buffer'; +import { ByteSizeValue } from '@kbn/config-schema'; +import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; +import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; +import type { MigrationResult } from '@kbn/core-saved-objects-base-server-internal'; +import { createInitialState } from './initial_state'; +import { Defer } from './kibana_migrator_utils'; +import { migrationStateActionMachine } from './migrations_state_action_machine'; +import { next } from './next'; +import { runResilientMigrator, type RunResilientMigratorParams } from './run_resilient_migrator'; +import { indexTypesMapMock, savedObjectTypeRegistryMock } from './run_resilient_migrator.fixtures'; +import type { InitState, State } from './state'; +import type { Next } from './state_action_machine'; + +const SOME_MIGRATION_RESULT: MigrationResult = { + sourceIndex: '.my_index_pre8.2.3_001', + destIndex: '.my_index_8.2.3_001', + elapsedMs: 16, + status: 'migrated', +}; + +jest.mock('./migrations_state_action_machine', () => { + const actual = jest.requireActual('./migrations_state_action_machine'); + return { + ...actual, + migrationStateActionMachine: jest.fn(() => Promise.resolve(SOME_MIGRATION_RESULT)), + }; +}); + +jest.mock('./initial_state', () => { + const actual = jest.requireActual('./initial_state'); + return { + ...actual, + createInitialState: jest.fn(actual.createInitialState), + }; +}); + +jest.mock('./next', () => { + const actual = jest.requireActual('./next'); + return { + ...actual, + next: jest.fn(actual.next), + }; +}); + +describe('runResilientMigrator', () => { + let options: RunResilientMigratorParams; + let initialState: InitState; + let migrationResult: MigrationResult; + let nextFunc: Next; + + beforeAll(async () => { + options = mockOptions(); + migrationResult = await runResilientMigrator(options); + }); + + it('calls createInitialState with the right params', () => { + expect(createInitialState).toHaveBeenCalledTimes(1); + expect(createInitialState).toHaveBeenCalledWith({ + kibanaVersion: options.kibanaVersion, + waitForMigrationCompletion: options.waitForMigrationCompletion, + mustRelocateDocuments: options.mustRelocateDocuments, + indexTypesMap: options.indexTypesMap, + targetMappings: options.targetMappings, + preMigrationScript: options.preMigrationScript, + migrationVersionPerType: options.migrationVersionPerType, + coreMigrationVersionPerType: options.coreMigrationVersionPerType, + indexPrefix: options.indexPrefix, + migrationsConfig: options.migrationsConfig, + typeRegistry: options.typeRegistry, + docLinks: options.docLinks, + logger: options.logger, + }); + + // store the created initial state + initialState = (createInitialState as jest.MockedFunction).mock + .results[0].value; + + // store the generated "next" function + nextFunc = (next as jest.MockedFunction).mock.results[0].value; + }); + + it('calls migrationStateMachine with the right params', () => { + expect(migrationStateActionMachine).toHaveBeenCalledTimes(1); + expect(migrationStateActionMachine).toHaveBeenCalledWith({ + initialState, + logger: options.logger, + next: nextFunc, + model: expect.any(Function), + abort: expect.any(Function), + }); + }); + + it('returns the result of migrationStateMachine', () => { + expect(migrationResult).toEqual(SOME_MIGRATION_RESULT); + }); +}); + +const mockOptions = (): RunResilientMigratorParams => { + const logger = loggingSystemMock.create().get(); + const mockedClient = elasticsearchClientMock.createElasticsearchClient(); + (mockedClient as any).child = jest.fn().mockImplementation(() => mockedClient); + + return { + client: mockedClient, + kibanaVersion: '8.8.0', + waitForMigrationCompletion: false, + mustRelocateDocuments: true, + indexTypesMap: indexTypesMapMock, + targetMappings: { + properties: { + a: { type: 'keyword' }, + c: { type: 'long' }, + }, + _meta: { + migrationMappingPropertyHashes: { + a: '000', + c: '222', + }, + }, + }, + readyToReindex: new Defer(), + doneReindexing: new Defer(), + logger, + transformRawDocs: jest.fn(), + preMigrationScript: "ctx._id = ctx._source.type + ':' + ctx._id", + migrationVersionPerType: { my_dashboard: '7.10.1', my_viz: '8.0.0' }, + coreMigrationVersionPerType: {}, + indexPrefix: '.my_index', + migrationsConfig: { + algorithm: 'v2' as const, + batchSize: 20, + maxBatchSizeBytes: ByteSizeValue.parse('20mb'), + maxReadBatchSizeBytes: new ByteSizeValue(buffer.constants.MAX_STRING_LENGTH), + pollInterval: 20000, + scrollDuration: '10m', + skip: false, + retryAttempts: 20, + zdt: { + metaPickupSyncDelaySec: 120, + runOnNonMigratorNodes: true, + }, + }, + typeRegistry: savedObjectTypeRegistryMock, + docLinks: docLinksServiceMock.createSetupContract(), + }; +}; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.ts index 4438847890b54..88f6f57578492 100644 --- a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.ts +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_resilient_migrator.ts @@ -40,6 +40,26 @@ import type { State } from './state'; */ export const MIGRATION_CLIENT_OPTIONS = { maxRetries: 0, requestTimeout: 120_000 }; +export interface RunResilientMigratorParams { + client: ElasticsearchClient; + kibanaVersion: string; + waitForMigrationCompletion: boolean; + mustRelocateDocuments: boolean; + indexTypesMap: IndexTypesMap; + targetMappings: IndexMapping; + preMigrationScript?: string; + readyToReindex: Defer; + doneReindexing: Defer; + logger: Logger; + transformRawDocs: TransformRawDocs; + coreMigrationVersionPerType: SavedObjectsMigrationVersion; + migrationVersionPerType: SavedObjectsMigrationVersion; + indexPrefix: string; + migrationsConfig: SavedObjectsMigrationConfigType; + typeRegistry: ISavedObjectTypeRegistry; + docLinks: DocLinksServiceStart; +} + /** * Migrates the provided indexPrefix index using a resilient algorithm that is * completely lock-free so that any failure can always be retried by @@ -63,25 +83,7 @@ export async function runResilientMigrator({ migrationsConfig, typeRegistry, docLinks, -}: { - client: ElasticsearchClient; - kibanaVersion: string; - waitForMigrationCompletion: boolean; - mustRelocateDocuments: boolean; - indexTypesMap: IndexTypesMap; - targetMappings: IndexMapping; - preMigrationScript?: string; - readyToReindex: Defer; - doneReindexing: Defer; - logger: Logger; - transformRawDocs: TransformRawDocs; - coreMigrationVersionPerType: SavedObjectsMigrationVersion; - migrationVersionPerType: SavedObjectsMigrationVersion; - indexPrefix: string; - migrationsConfig: SavedObjectsMigrationConfigType; - typeRegistry: ISavedObjectTypeRegistry; - docLinks: DocLinksServiceStart; -}): Promise { +}: RunResilientMigratorParams): Promise { const initialState = createInitialState({ kibanaVersion, waitForMigrationCompletion, diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.test.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.test.ts new file mode 100644 index 0000000000000..22d62307aacf8 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.test.ts @@ -0,0 +1,273 @@ +/* + * Copyright 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 buffer from 'buffer'; +import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; +import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import { + type MigrationResult, + SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; +import { ByteSizeValue } from '@kbn/config-schema'; +import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; +import { runV2Migration, RunV2MigrationOpts } from './run_v2_migration'; +import { DocumentMigrator } from './document_migrator'; +import { ALLOWED_CONVERT_VERSION } from './kibana_migrator_constants'; +import { buildTypesMappings, createIndexMap } from './core'; +import { + getIndicesInvolvedInRelocation, + indexMapToIndexTypesMap, + createMultiPromiseDefer, + Defer, +} from './kibana_migrator_utils'; +import { runResilientMigrator } from './run_resilient_migrator'; +import { indexTypesMapMock, savedObjectTypeRegistryMock } from './run_resilient_migrator.fixtures'; + +jest.mock('./core', () => { + const actual = jest.requireActual('./core'); + return { + ...actual, + createIndexMap: jest.fn(actual.createIndexMap), + }; +}); + +jest.mock('./kibana_migrator_utils', () => { + const actual = jest.requireActual('./kibana_migrator_utils'); + return { + ...actual, + indexMapToIndexTypesMap: jest.fn(actual.indexMapToIndexTypesMap), + createMultiPromiseDefer: jest.fn(actual.createMultiPromiseDefer), + getIndicesInvolvedInRelocation: jest.fn(() => Promise.resolve(['.my_index', '.other_index'])), + }; +}); + +const V2_SUCCESSFUL_MIGRATION_RESULT: MigrationResult[] = [ + { + sourceIndex: '.my_index_pre8.2.3_001', + destIndex: '.my_index_8.2.3_001', + elapsedMs: 16, + status: 'migrated', + }, + { + sourceIndex: '.other_index_pre8.2.3_001', + destIndex: '.other_index_8.2.3_001', + elapsedMs: 8, + status: 'migrated', + }, + { + destIndex: '.task_index_8.2.3_001', + elapsedMs: 4, + status: 'patched', + }, +]; + +jest.mock('./run_resilient_migrator', () => { + const actual = jest.requireActual('./run_resilient_migrator'); + return { + ...actual, + runResilientMigrator: jest.fn(() => Promise.resolve(V2_SUCCESSFUL_MIGRATION_RESULT)), + }; +}); + +const nextTick = () => new Promise((resolve) => setImmediate(resolve)); +const mockCreateIndexMap = createIndexMap as jest.MockedFunction; +const mockIndexMapToIndexTypesMap = indexMapToIndexTypesMap as jest.MockedFunction< + typeof indexMapToIndexTypesMap +>; +const mockCreateMultiPromiseDefer = createMultiPromiseDefer as jest.MockedFunction< + typeof createMultiPromiseDefer +>; +const mockGetIndicesInvolvedInRelocation = getIndicesInvolvedInRelocation as jest.MockedFunction< + typeof getIndicesInvolvedInRelocation +>; +const mockRunResilientMigrator = runResilientMigrator as jest.MockedFunction< + typeof runResilientMigrator +>; + +describe('runV2Migration', () => { + beforeEach(() => { + mockCreateIndexMap.mockClear(); + mockIndexMapToIndexTypesMap.mockClear(); + mockCreateMultiPromiseDefer.mockClear(); + mockGetIndicesInvolvedInRelocation.mockClear(); + mockRunResilientMigrator.mockClear(); + }); + + it('rejects if prepare migrations has not been called on the documentMigrator', async () => { + const options = mockOptions(); + await expect(runV2Migration(options)).rejects.toEqual( + new Error('Migrations are not ready. Make sure prepareMigrations is called first.') + ); + }); + + it('calls createIndexMap with the right params', async () => { + const options = mockOptions(); + options.documentMigrator.prepareMigrations(); + await runV2Migration(options); + expect(createIndexMap).toBeCalledTimes(1); + expect(createIndexMap).toBeCalledWith({ + kibanaIndexName: options.kibanaIndexPrefix, + indexMap: options.mappingProperties, + registry: options.typeRegistry, + }); + }); + + it('calls indexMapToIndexTypesMap with the result from createIndexMap', async () => { + const options = mockOptions(); + options.documentMigrator.prepareMigrations(); + await runV2Migration(options); + expect(indexMapToIndexTypesMap).toBeCalledTimes(1); + expect(indexMapToIndexTypesMap).toBeCalledWith(mockCreateIndexMap.mock.results[0].value); + }); + + it('calls getIndicesInvolvedInRelocation with the right params', async () => { + const options = mockOptions(); + options.documentMigrator.prepareMigrations(); + await runV2Migration(options); + expect(getIndicesInvolvedInRelocation).toBeCalledTimes(1); + expect(getIndicesInvolvedInRelocation).toBeCalledWith( + expect.objectContaining({ + client: options.elasticsearchClient, + indexTypesMap: mockIndexMapToIndexTypesMap.mock.results[0].value, + logger: options.logger, + }) + ); + }); + + it('calls createMultiPromiseDefer, with the list of moving indices', async () => { + const options = mockOptions(); + options.documentMigrator.prepareMigrations(); + await runV2Migration(options); + expect(createMultiPromiseDefer).toBeCalledTimes(2); + expect(createMultiPromiseDefer).toHaveBeenNthCalledWith(1, ['.my_index', '.other_index']); + expect(createMultiPromiseDefer).toHaveBeenNthCalledWith(2, ['.my_index', '.other_index']); + }); + + it('calls runResilientMigrator for each migrator it must spawn', async () => { + const options = mockOptions(); + options.documentMigrator.prepareMigrations(); + await runV2Migration(options); + expect(runResilientMigrator).toHaveBeenCalledTimes(3); + const runResilientMigratorCommonParams = { + client: options.elasticsearchClient, + kibanaVersion: options.kibanaVersion, + logger: options.logger, + migrationsConfig: options.migrationConfig, + typeRegistry: options.typeRegistry, + }; + expect(runResilientMigrator).toHaveBeenNthCalledWith( + 1, + expect.objectContaining({ + ...runResilientMigratorCommonParams, + indexPrefix: '.my_index', + mustRelocateDocuments: true, + readyToReindex: expect.any(Object), + doneReindexing: expect.any(Object), + }) + ); + expect(runResilientMigrator).toHaveBeenNthCalledWith( + 2, + expect.objectContaining({ + ...runResilientMigratorCommonParams, + indexPrefix: '.other_index', + mustRelocateDocuments: true, + readyToReindex: expect.any(Object), + doneReindexing: expect.any(Object), + }) + ); + expect(runResilientMigrator).toHaveBeenNthCalledWith( + 3, + expect.objectContaining({ + ...runResilientMigratorCommonParams, + indexPrefix: '.task_index', + mustRelocateDocuments: false, + readyToReindex: undefined, + doneReindexing: undefined, + }) + ); + }); + + it('awaits on all runResilientMigrator promises, and resolves with the results of each of them', async () => { + const myIndexMigratorDefer = new Defer(); + const otherIndexMigratorDefer = new Defer(); + const taskIndexMigratorDefer = new Defer(); + let migrationResults: MigrationResult[] | undefined; + + mockRunResilientMigrator.mockReturnValueOnce(myIndexMigratorDefer.promise); + mockRunResilientMigrator.mockReturnValueOnce(otherIndexMigratorDefer.promise); + mockRunResilientMigrator.mockReturnValueOnce(taskIndexMigratorDefer.promise); + const options = mockOptions(); + options.documentMigrator.prepareMigrations(); + + runV2Migration(options).then((results) => (migrationResults = results)); + await nextTick(); + expect(migrationResults).toBeUndefined(); + myIndexMigratorDefer.resolve(V2_SUCCESSFUL_MIGRATION_RESULT[0]); + otherIndexMigratorDefer.resolve(V2_SUCCESSFUL_MIGRATION_RESULT[1]); + await nextTick(); + expect(migrationResults).toBeUndefined(); + taskIndexMigratorDefer.resolve(V2_SUCCESSFUL_MIGRATION_RESULT[2]); + await nextTick(); + expect(migrationResults).toEqual(V2_SUCCESSFUL_MIGRATION_RESULT); + }); + + it('rejects if one of the runResilientMigrator promises rejects', async () => { + mockRunResilientMigrator.mockResolvedValueOnce(V2_SUCCESSFUL_MIGRATION_RESULT[0]); + mockRunResilientMigrator.mockResolvedValueOnce(V2_SUCCESSFUL_MIGRATION_RESULT[1]); + const myTaskIndexMigratorError = new Error( + 'Something terrible and unexpected happened whilst tyring to migrate .task_index' + ); + mockRunResilientMigrator.mockRejectedValueOnce(myTaskIndexMigratorError); + const options = mockOptions(); + options.documentMigrator.prepareMigrations(); + + await expect(runV2Migration(options)).rejects.toThrowError(myTaskIndexMigratorError); + }); +}); + +const mockOptions = (kibanaVersion = '8.2.3'): RunV2MigrationOpts => { + const mockedClient = elasticsearchClientMock.createElasticsearchClient(); + (mockedClient as any).child = jest.fn().mockImplementation(() => mockedClient); + + const typeRegistry = savedObjectTypeRegistryMock; + + const logger = loggingSystemMock.create().get(); + + return { + logger, + kibanaVersion, + waitForMigrationCompletion: false, + typeRegistry, + kibanaIndexPrefix: '.my_index', + defaultIndexTypesMap: indexTypesMapMock, + migrationConfig: { + algorithm: 'v2' as const, + batchSize: 20, + maxBatchSizeBytes: ByteSizeValue.parse('20mb'), + maxReadBatchSizeBytes: new ByteSizeValue(buffer.constants.MAX_STRING_LENGTH), + pollInterval: 20000, + scrollDuration: '10m', + skip: false, + retryAttempts: 20, + zdt: { + metaPickupSyncDelaySec: 120, + runOnNonMigratorNodes: true, + }, + }, + elasticsearchClient: mockedClient, + docLinks: docLinksServiceMock.createSetupContract(), + documentMigrator: new DocumentMigrator({ + kibanaVersion, + convertVersion: ALLOWED_CONVERT_VERSION, + typeRegistry, + log: logger, + }), + serializer: new SavedObjectsSerializer(typeRegistry), + mappingProperties: buildTypesMappings(typeRegistry.getAllTypes()), + }; +}; diff --git a/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.ts b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.ts new file mode 100644 index 0000000000000..c50a3c6997598 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-migration-server-internal/src/run_v2_migration.ts @@ -0,0 +1,153 @@ +/* + * Copyright 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 { Logger } from '@kbn/logging'; +import type { DocLinksServiceStart } from '@kbn/core-doc-links-server'; +import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import type { + ISavedObjectTypeRegistry, + ISavedObjectsSerializer, + SavedObjectsRawDoc, +} from '@kbn/core-saved-objects-server'; +import type { + IndexTypesMap, + MigrationResult, + SavedObjectsMigrationConfigType, + SavedObjectsTypeMappingDefinitions, +} from '@kbn/core-saved-objects-base-server-internal'; +import Semver from 'semver'; +import type { DocumentMigrator } from './document_migrator'; +import { buildActiveMappings, createIndexMap } from './core'; +import { + createMultiPromiseDefer, + getIndicesInvolvedInRelocation, + indexMapToIndexTypesMap, +} from './kibana_migrator_utils'; +import { runResilientMigrator } from './run_resilient_migrator'; +import { migrateRawDocsSafely } from './core/migrate_raw_docs'; + +export interface RunV2MigrationOpts { + /** The current Kibana version */ + kibanaVersion: string; + /** The default Kibana SavedObjects index prefix. e.g `.kibana` */ + kibanaIndexPrefix: string; + /** The SO type registry to use for the migration */ + typeRegistry: ISavedObjectTypeRegistry; + /** The map of indices => types to use as a default / baseline state */ + defaultIndexTypesMap: IndexTypesMap; + /** Logger to use for migration output */ + logger: Logger; + /** The document migrator to use to convert the document */ + documentMigrator: DocumentMigrator; + /** docLinks contract to use to link to documentation */ + docLinks: DocLinksServiceStart; + /** SO serializer to use for migration */ + serializer: ISavedObjectsSerializer; + /** The client to use for communications with ES */ + elasticsearchClient: ElasticsearchClient; + /** The configuration that drives the behavior of each migrator */ + migrationConfig: SavedObjectsMigrationConfigType; + /** The definitions of the different saved object types */ + mappingProperties: SavedObjectsTypeMappingDefinitions; + /** Tells whether this instance should actively participate in the migration or not */ + waitForMigrationCompletion: boolean; +} + +export const runV2Migration = async (options: RunV2MigrationOpts): Promise => { + const indexMap = createIndexMap({ + kibanaIndexName: options.kibanaIndexPrefix, + indexMap: options.mappingProperties, + registry: options.typeRegistry, + }); + + options.logger.debug('Applying registered migrations for the following saved object types:'); + Object.entries(options.documentMigrator.getMigrationVersion()) + .sort(([t1, v1], [t2, v2]) => { + return Semver.compare(v1, v2); + }) + .forEach(([type, migrationVersion]) => { + options.logger.debug(`migrationVersion: ${migrationVersion} saved object type: ${type}`); + }); + + // build a indexTypesMap from the info present in tye typeRegistry, e.g.: + // { + // '.kibana': ['typeA', 'typeB', ...] + // '.kibana_task_manager': ['task', ...] + // '.kibana_cases': ['typeC', 'typeD', ...] + // ... + // } + const indexTypesMap = indexMapToIndexTypesMap(indexMap); + + // compare indexTypesMap with the one present (or not) in the .kibana index meta + // and check if some SO types have been moved to different indices + const indicesWithMovingTypes = await getIndicesInvolvedInRelocation({ + mainIndex: options.kibanaIndexPrefix, + client: options.elasticsearchClient, + indexTypesMap, + logger: options.logger, + defaultIndexTypesMap: options.defaultIndexTypesMap, + }); + + // we create 2 synchronization objects (2 synchronization points) for each of the + // migrators involved in relocations, aka each of the migrators that will: + // A) reindex some documents TO other indices + // B) receive some documents FROM other indices + // C) both + const readyToReindexDefers = createMultiPromiseDefer(indicesWithMovingTypes); + const doneReindexingDefers = createMultiPromiseDefer(indicesWithMovingTypes); + + // build a list of all migrators that must be started + const migratorIndices = new Set(Object.keys(indexMap)); + // indices involved in a relocation might no longer be present in current mappings + // but if their SOs must be relocated to another index, we still need a migrator to do the job + indicesWithMovingTypes.forEach((index) => migratorIndices.add(index)); + + const migrators = Array.from(migratorIndices).map((indexName, i) => { + return { + migrate: (): Promise => { + const readyToReindex = readyToReindexDefers[indexName]; + const doneReindexing = doneReindexingDefers[indexName]; + // check if this migrator's index is involved in some document redistribution + const mustRelocateDocuments = !!readyToReindex; + + return runResilientMigrator({ + client: options.elasticsearchClient, + kibanaVersion: options.kibanaVersion, + mustRelocateDocuments, + indexTypesMap, + waitForMigrationCompletion: options.waitForMigrationCompletion, + // a migrator's index might no longer have any associated types to it + targetMappings: buildActiveMappings(indexMap[indexName]?.typeMappings ?? {}), + logger: options.logger, + preMigrationScript: indexMap[indexName]?.script, + readyToReindex, + doneReindexing, + transformRawDocs: (rawDocs: SavedObjectsRawDoc[]) => + migrateRawDocsSafely({ + serializer: options.serializer, + migrateDoc: options.documentMigrator.migrateAndConvert, + rawDocs, + }), + coreMigrationVersionPerType: options.documentMigrator.getMigrationVersion({ + includeDeferred: false, + migrationType: 'core', + }), + migrationVersionPerType: options.documentMigrator.getMigrationVersion({ + includeDeferred: false, + }), + indexPrefix: indexName, + migrationsConfig: options.migrationConfig, + typeRegistry: options.typeRegistry, + docLinks: options.docLinks, + }); + }, + }; + }); + + return Promise.all(migrators.map((migrator) => migrator.migrate())); +}; diff --git a/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.ts b/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.ts index d73073d131084..51f7f29e9683a 100644 --- a/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.ts +++ b/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.ts @@ -38,6 +38,7 @@ import { type SavedObjectsConfigType, type SavedObjectsMigrationConfigType, type IKibanaMigrator, + DEFAULT_INDEX_TYPES_MAP, } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsClient, @@ -376,6 +377,7 @@ export class SavedObjectsService kibanaVersion: this.kibanaVersion, soMigrationsConfig, kibanaIndex: MAIN_SAVED_OBJECT_INDEX, + defaultIndexTypesMap: DEFAULT_INDEX_TYPES_MAP, client, docLinks, waitForMigrationCompletion, diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/active_delete_multiple_instances.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/active_delete_multiple_instances.test.ts index 57e4844ef3182..e297b39847f10 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/active_delete_multiple_instances.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/active_delete_multiple_instances.test.ts @@ -15,6 +15,7 @@ import { REPO_ROOT } from '@kbn/repo-info'; import { type TestElasticsearchUtils } from '@kbn/core-test-helpers-kbn-server'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import type { SavedObjectsBulkCreateObject } from '@kbn/core-saved-objects-api-server'; +import { DEFAULT_INDEX_TYPES_MAP } from '@kbn/core-saved-objects-base-server-internal'; import { defaultLogFilePath, getEsClient, @@ -113,6 +114,7 @@ describe('multiple migrator instances running in parallel', () => { getKibanaMigratorTestKit({ ...config, logFilePath: Path.join(__dirname, `active_delete_instance_${index}.log`), + defaultIndexTypesMap: DEFAULT_INDEX_TYPES_MAP, }) ) ); 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 3eaca3a8e553c..626a89df410a8 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 @@ -13,6 +13,7 @@ import { type SavedObjectsType, MAIN_SAVED_OBJECT_INDEX, } from '@kbn/core-saved-objects-server'; +import { DEFAULT_INDEX_TYPES_MAP } from '@kbn/core-saved-objects-base-server-internal'; import { clearLog, startElasticsearch, @@ -80,6 +81,7 @@ describe('split .kibana index into multiple system indices', () => { types: updatedTypeRegistry.getAllTypes(), kibanaIndex: '.kibana', logFilePath, + defaultIndexTypesMap: DEFAULT_INDEX_TYPES_MAP, }); const { runMigrations, client } = await migratorTestKitFactory(); diff --git a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts index 43d5cc746a7e3..57258aef0916e 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts @@ -24,6 +24,7 @@ import { SavedObjectTypeRegistry, type IKibanaMigrator, type MigrationResult, + type IndexTypesMap, } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsRepository } from '@kbn/core-saved-objects-api-server-internal'; import { @@ -73,6 +74,7 @@ export interface KibanaMigratorTestKitParams { nodeRoles?: NodeRoles; settings?: Record; types?: Array>; + defaultIndexTypesMap?: IndexTypesMap; logFilePath?: string; } @@ -126,6 +128,7 @@ export const getEsClient = async ({ export const getKibanaMigratorTestKit = async ({ settings = {}, kibanaIndex = defaultKibanaIndex, + defaultIndexTypesMap = {}, // do NOT assume any types are stored in any index by default kibanaVersion = currentVersion, kibanaBranch = currentBranch, types = [], @@ -149,16 +152,17 @@ export const getKibanaMigratorTestKit = async ({ // types must be registered before instantiating the migrator registerTypes(typeRegistry, types); - const migrator = await getMigrator( + const migrator = await getMigrator({ configService, client, typeRegistry, loggerFactory, kibanaIndex, + defaultIndexTypesMap, kibanaVersion, kibanaBranch, - nodeRoles - ); + nodeRoles, + }); const runMigrations = async () => { if (hasRun) { @@ -261,16 +265,28 @@ const getElasticsearchClient = async ( }); }; -const getMigrator = async ( - configService: ConfigService, - client: ElasticsearchClient, - typeRegistry: ISavedObjectTypeRegistry, - loggerFactory: LoggerFactory, - kibanaIndex: string, - kibanaVersion: string, - kibanaBranch: string, - nodeRoles: NodeRoles -) => { +interface GetMigratorParams { + configService: ConfigService; + client: ElasticsearchClient; + kibanaIndex: string; + typeRegistry: ISavedObjectTypeRegistry; + defaultIndexTypesMap: IndexTypesMap; + loggerFactory: LoggerFactory; + kibanaVersion: string; + kibanaBranch: string; + nodeRoles: NodeRoles; +} +const getMigrator = async ({ + configService, + client, + kibanaIndex, + typeRegistry, + defaultIndexTypesMap, + loggerFactory, + kibanaVersion, + kibanaBranch, + nodeRoles, +}: GetMigratorParams) => { const savedObjectsConf = await firstValueFrom( configService.atPath('savedObjects') ); @@ -286,8 +302,9 @@ const getMigrator = async ( return new KibanaMigrator({ client, - typeRegistry, kibanaIndex, + typeRegistry, + defaultIndexTypesMap, soMigrationsConfig: soConfig.migration, kibanaVersion, logger: loggerFactory.get('savedobjects-service'), From f5d37e75fa1b410e22b57dc99aa4f7a449a6d1df Mon Sep 17 00:00:00 2001 From: Stef Nestor <26751266+stefnestor@users.noreply.github.com> Date: Thu, 1 Jun 2023 07:50:02 -0600 Subject: [PATCH 27/31] [DOC+] Move logging location reference (#158521) Per https://github.com/elastic/kibana/pull/158379 , this moves the "this is where you find Kibana logs on the server" from under [Kibana Not Ready error](https://www.elastic.co/guide/en/kibana/master/access.html#not-ready) onto the [Log Settings](https://www.elastic.co/guide/en/kibana/master/logs-ui-settings-kb.html) page. --- docs/settings/logs-ui-settings.asciidoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/settings/logs-ui-settings.asciidoc b/docs/settings/logs-ui-settings.asciidoc index e7321b7f0768c..7d86a85680863 100644 --- a/docs/settings/logs-ui-settings.asciidoc +++ b/docs/settings/logs-ui-settings.asciidoc @@ -7,6 +7,13 @@ You do not need to configure any settings to use the Logs app in {kib}. It is enabled by default. +The {kib} logs can be found per operating system under: + +* Linux, DEB or RPM package: /var/log/kibana/kibana.log +* Linux, tar.gz package: $KIBANA_HOME/log/kibana.log +* Windows: $KIBANA_HOME\log\kibana.log + + [float] [[general-logs-ui-settings-kb]] ==== General Logs settings From 648c669034bc2250323fc43e0a3571691ff192a1 Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Thu, 1 Jun 2023 15:55:01 +0200 Subject: [PATCH 28/31] removing references to saved object client in lens and graph (#158645) --- .../saved_objects_utils/save_with_confirmation.ts | 2 +- .../form_based/dimension_panel/dimension_editor.tsx | 1 - .../dimension_panel/dimension_panel.test.tsx | 9 +-------- .../form_based/dimension_panel/dimension_panel.tsx | 8 +------- .../dimension_panel/reference_editor.test.tsx | 3 +-- .../form_based/dimension_panel/reference_editor.tsx | 3 +-- .../lens/public/datasources/form_based/form_based.tsx | 1 - .../operations/definitions/date_histogram.test.tsx | 3 +-- .../operations/definitions/filters/filters.test.tsx | 3 +-- .../form_based/operations/definitions/index.ts | 8 +------- .../operations/definitions/last_value.test.tsx | 3 +-- .../operations/definitions/percentile.test.tsx | 11 +++++------ .../operations/definitions/percentile_ranks.test.tsx | 3 +-- .../operations/definitions/ranges/ranges.test.tsx | 3 +-- .../operations/definitions/static_value.test.tsx | 3 +-- .../operations/definitions/terms/terms.test.tsx | 3 +-- 16 files changed, 18 insertions(+), 49 deletions(-) diff --git a/x-pack/plugins/graph/public/helpers/saved_objects_utils/save_with_confirmation.ts b/x-pack/plugins/graph/public/helpers/saved_objects_utils/save_with_confirmation.ts index 35bcc6748dacc..32fd20d782b96 100644 --- a/x-pack/plugins/graph/public/helpers/saved_objects_utils/save_with_confirmation.ts +++ b/x-pack/plugins/graph/public/helpers/saved_objects_utils/save_with_confirmation.ts @@ -21,7 +21,7 @@ import { GraphWorkspaceSavedObject } from '../../types'; * @param source - serialized version of this object what will be indexed into elasticsearch. * @param savedObject - VisSavedObject * @param options - options to pass to the saved object create method - * @param services - provides Kibana services savedObjectsClient and overlays + * @param services - provides Kibana services contentClient and overlays * @returns {Promise} - A promise that is resolved with the objects id if the object is * successfully indexed. If the overwrite confirmation was rejected, an error is thrown with * a confirmRejected = true parameter so that case can be handled differently than diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx index c43bf5d0c68bb..688e828a7bbd0 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx @@ -113,7 +113,6 @@ export function DimensionEditor(props: DimensionEditorProps) { data: props.data, fieldFormats: props.fieldFormats, uiSettings: props.uiSettings, - savedObjectsClient: props.savedObjectsClient, http: props.http, storage: props.storage, unifiedSearch: props.unifiedSearch, diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.test.tsx index a4fd8135f00be..269d82c6c6e46 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.test.tsx @@ -25,13 +25,7 @@ import { FormBasedDimensionEditorProps, } from './dimension_panel'; import { mountWithIntl as mount, shallowWithIntl as shallow } from '@kbn/test-jest-helpers'; -import { - IUiSettingsClient, - SavedObjectsClientContract, - HttpSetup, - CoreStart, - NotificationsStart, -} from '@kbn/core/public'; +import { IUiSettingsClient, HttpSetup, CoreStart, NotificationsStart } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { useExistingFieldsReader } from '@kbn/unified-field-list-plugin/public/hooks/use_existing_fields'; import { generateId } from '../../../id_generator'; @@ -228,7 +222,6 @@ describe('FormBasedDimensionEditor', () => { filterOperations: () => true, storage: {} as IStorageWrapper, uiSettings: {} as IUiSettingsClient, - savedObjectsClient: {} as SavedObjectsClientContract, http: {} as HttpSetup, fieldFormats: fieldFormatsServiceMock.createStartContract(), unifiedSearch: unifiedSearchPluginMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.tsx index dd3a66e26f036..546deb29e26fa 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.tsx @@ -6,12 +6,7 @@ */ import React, { memo } from 'react'; -import type { - IUiSettingsClient, - SavedObjectsClientContract, - HttpSetup, - NotificationsStart, -} from '@kbn/core/public'; +import type { IUiSettingsClient, HttpSetup, NotificationsStart } from '@kbn/core/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; @@ -34,7 +29,6 @@ export type FormBasedDimensionEditorProps = DatasourceDimensionEditorProps & { uiSettings: IUiSettingsClient; storage: IStorageWrapper; - savedObjectsClient: SavedObjectsClientContract; layerId: string; http: HttpSetup; data: DataPublicPluginStart; diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.test.tsx index 74a43f3e7db21..8a5163a3a27d2 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.test.tsx @@ -13,7 +13,7 @@ import { mountWithIntl as mount } from '@kbn/test-jest-helpers'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; -import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import type { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { OperationMetadata } from '../../../types'; @@ -73,7 +73,6 @@ describe('reference editor', () => { dateRange: { fromDate: 'now-1d', toDate: 'now' }, storage: {} as IStorageWrapper, uiSettings: {} as IUiSettingsClient, - savedObjectsClient: {} as SavedObjectsClientContract, http: {} as HttpSetup, data: {} as DataPublicPluginStart, fieldFormats: fieldFormatsServiceMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx index 53fe225d4d926..d298267f0a8b7 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx @@ -10,7 +10,7 @@ import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRowProps, EuiSpacer, EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; -import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import type { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; @@ -98,7 +98,6 @@ export interface ReferenceEditorProps { // Services uiSettings: IUiSettingsClient; storage: IStorageWrapper; - savedObjectsClient: SavedObjectsClientContract; http: HttpSetup; data: DataPublicPluginStart; fieldFormats: FieldFormatsStart; diff --git a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx index e8a4e0bf590fd..b89bb9e6e3f38 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx @@ -578,7 +578,6 @@ export function getFormBasedDatasource({ uiSettings={uiSettings} storage={storage} fieldFormats={fieldFormats} - savedObjectsClient={core.savedObjects.client} http={core.http} data={data} unifiedSearch={unifiedSearch} diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.test.tsx index d9510256eb92d..9259fb2cd9c98 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.test.tsx @@ -13,7 +13,7 @@ import { EuiSwitch } from '@elastic/eui'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import type { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { UI_SETTINGS } from '@kbn/data-plugin/public'; import { dataPluginMock, getCalculateAutoTimeExpression } from '@kbn/data-plugin/public/mocks'; @@ -98,7 +98,6 @@ const defaultOptions = { layerId: '1', storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1y', toDate: 'now', diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.test.tsx index e5199a5295ec6..5f27106a5ab44 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.test.tsx @@ -10,7 +10,7 @@ import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; -import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import type { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; @@ -25,7 +25,6 @@ const uiSettingsMock = {} as IUiSettingsClient; const defaultProps = { storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts index f050604cfc0d0..aaba48eae39d0 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts @@ -5,12 +5,7 @@ * 2.0. */ -import { - IUiSettingsClient, - SavedObjectsClientContract, - HttpSetup, - CoreStart, -} from '@kbn/core/public'; +import { IUiSettingsClient, HttpSetup, CoreStart } from '@kbn/core/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { ExpressionAstExpressionBuilder, @@ -189,7 +184,6 @@ export interface ParamEditorProps< indexPattern: IndexPattern; uiSettings: IUiSettingsClient; storage: IStorageWrapper; - savedObjectsClient: SavedObjectsClientContract; http: HttpSetup; dateRange: DateRange; data: DataPublicPluginStart; diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx index 6ba5ed0056c38..47f8d6f2bd2e0 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx @@ -10,7 +10,7 @@ import { shallow, ShallowWrapper } from 'enzyme'; import { EuiComboBox, EuiFormRow } from '@elastic/eui'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; -import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; @@ -27,7 +27,6 @@ const uiSettingsMock = {} as IUiSettingsClient; const defaultProps = { storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, fieldFormats: fieldFormatsServiceMock.createStartContract(), unifiedSearch: unifiedSearchPluginMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.test.tsx index 51385cfac9cc8..4b9bfcd0171cd 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.test.tsx @@ -8,7 +8,7 @@ import React, { ChangeEvent } from 'react'; import { act } from 'react-dom/test-utils'; import { EuiRange } from '@elastic/eui'; -import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import { EuiFormRow } from '@elastic/eui'; import { shallow, mount } from 'enzyme'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; @@ -45,7 +45,6 @@ const uiSettingsMock = {} as IUiSettingsClient; const defaultProps = { storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(), @@ -220,19 +219,19 @@ describe('percentile', () => { ], // filtered [ - `aggFilteredMetric id="2" enabled=true schema="metric" + `aggFilteredMetric id="2" enabled=true schema="metric" customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} customMetric={aggSinglePercentile id="2" enabled=true schema="metric" field="foo" percentile=10}`, - `aggFilteredMetric id="3" enabled=true schema="metric" + `aggFilteredMetric id="3" enabled=true schema="metric" customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} customMetric={aggSinglePercentile id="2" enabled=true schema="metric" field="foo" percentile=10}`, ], // different filter [ - `aggFilteredMetric id="4" enabled=true schema="metric" + `aggFilteredMetric id="4" enabled=true schema="metric" customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} customMetric={aggSinglePercentile id="2" enabled=true schema="metric" field="foo" percentile=10}`, - `aggFilteredMetric id="5" enabled=true schema="metric" + `aggFilteredMetric id="5" enabled=true schema="metric" customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} customMetric={aggSinglePercentile id="2" enabled=true schema="metric" field="foo" percentile=10}`, ], diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.test.tsx index c29e5ca2c1499..28cc1cedcd804 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { EuiFieldNumber } from '@elastic/eui'; -import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import { EuiFormRow } from '@elastic/eui'; import { shallow, mount } from 'enzyme'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; @@ -37,7 +37,6 @@ const uiSettingsMock = {} as IUiSettingsClient; const defaultProps = { storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx index 8972a78b5d9f7..f707197490e04 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { EuiFieldNumber, EuiRange, EuiButtonEmpty, EuiLink, EuiText } from '@elastic/eui'; -import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; @@ -85,7 +85,6 @@ const sourceField = 'MyField'; const defaultOptions = { storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1y', toDate: 'now', diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.test.tsx index e995b9b27a49d..30bbeaba9cb01 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { EuiFieldNumber } from '@elastic/eui'; -import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { shallow, mount } from 'enzyme'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; @@ -40,7 +40,6 @@ const dateRange = { const defaultProps = { storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(), diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/terms.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/terms.test.tsx index 640ceee14351d..609052b893270 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/terms.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/terms.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { shallow, mount } from 'enzyme'; import { EuiButtonGroup, EuiComboBox, EuiFieldNumber, EuiSelect, EuiSwitch } from '@elastic/eui'; -import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; +import type { IUiSettingsClient, HttpSetup } from '@kbn/core/public'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; @@ -88,7 +88,6 @@ const uiSettingsMock = {} as IUiSettingsClient; const defaultProps = { storage: {} as IStorageWrapper, uiSettings: uiSettingsMock, - savedObjectsClient: {} as SavedObjectsClientContract, dateRange: { fromDate: 'now-1d', toDate: 'now' }, data: dataPluginMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(), From 423cb35fd76390a0aa43a289df49a2caa653525d Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Thu, 1 Jun 2023 16:36:59 +0200 Subject: [PATCH 29/31] [ML] Versioning AIOps APIs (#158806) Adds versioning to the AIOps API. Versions are added to the server side routes and to the client side functions which call the routes. Updates API tests to add the API version to the request headers. The single API endpoint is already internal and now has been given the version '1'. **Internal APIs** `/internal/aiops/explain_log_rate_spikes` --- .../app/pages/page_reducer_stream/index.tsx | 1 + .../pages/page_simple_string_stream/index.tsx | 2 +- .../server/routes/reducer_stream.ts | 193 +-- .../server/routes/single_string_stream.ts | 95 +- .../ml/aiops_utils/src/fetch_stream.ts | 5 + .../aiops_utils/src/get_window_parameters.ts | 20 + .../ml/aiops_utils/src/use_fetch_stream.ts | 107 +- x-pack/packages/ml/aiops_utils/tsconfig.json | 1 + x-pack/plugins/aiops/common/api/index.ts | 1 + .../explain_log_rate_spikes_analysis.tsx | 1 + .../server/routes/explain_log_rate_spikes.ts | 1067 +++++++++-------- .../explain_log_rate_spikes_full_analysis.ts | 4 +- .../explain_log_rate_spikes_groups_only.ts | 4 +- .../aiops/explain_log_rate_spikes_no_index.ts | 2 + 14 files changed, 828 insertions(+), 675 deletions(-) diff --git a/examples/response_stream/public/containers/app/pages/page_reducer_stream/index.tsx b/examples/response_stream/public/containers/app/pages/page_reducer_stream/index.tsx index 913f8b4064440..713e2307938f7 100644 --- a/examples/response_stream/public/containers/app/pages/page_reducer_stream/index.tsx +++ b/examples/response_stream/public/containers/app/pages/page_reducer_stream/index.tsx @@ -51,6 +51,7 @@ export const PageReducerStream: FC = () => { typeof basePath >( `${basePath}/internal/response_stream/reducer_stream`, + '1', { compressResponse, simulateErrors }, { reducer: reducerStreamReducer, initialState } ); diff --git a/examples/response_stream/public/containers/app/pages/page_simple_string_stream/index.tsx b/examples/response_stream/public/containers/app/pages/page_simple_string_stream/index.tsx index 35b1cf07ed63b..149174b04e3ea 100644 --- a/examples/response_stream/public/containers/app/pages/page_simple_string_stream/index.tsx +++ b/examples/response_stream/public/containers/app/pages/page_simple_string_stream/index.tsx @@ -34,7 +34,7 @@ export const PageSimpleStringStream: FC = () => { const { dispatch, errors, start, cancel, data, isRunning } = useFetchStream< ApiSimpleStringStream, typeof basePath - >(`${basePath}/internal/response_stream/simple_string_stream`, { + >(`${basePath}/internal/response_stream/simple_string_stream`, '1', { compressResponse, timeout: 500, }); diff --git a/examples/response_stream/server/routes/reducer_stream.ts b/examples/response_stream/server/routes/reducer_stream.ts index e9fe6d02b68f6..1546583c6d3bc 100644 --- a/examples/response_stream/server/routes/reducer_stream.ts +++ b/examples/response_stream/server/routes/reducer_stream.ts @@ -20,103 +20,110 @@ import { import { API_ENDPOINT } from '../../common/api'; export const defineReducerStreamRoute = (router: IRouter, logger: Logger) => { - router.post( - { + router.versioned + .post({ path: API_ENDPOINT.REDUCER_STREAM, - validate: { - body: reducerStreamRequestBodySchema, + access: 'internal', + }) + .addVersion( + { + version: '1', + validate: { + request: { + body: reducerStreamRequestBodySchema, + }, + }, }, - }, - async (context, request, response) => { - const maxTimeoutMs = request.body.timeout ?? 250; - const simulateError = request.body.simulateErrors ?? false; - - let logMessageCounter = 1; - - function logDebugMessage(msg: string) { - logger.debug(`Response Stream Example #${logMessageCounter}: ${msg}`); - logMessageCounter++; - } - - logDebugMessage('Starting stream.'); - - let shouldStop = false; - request.events.aborted$.subscribe(() => { - logDebugMessage('aborted$ subscription trigger.'); - shouldStop = true; - }); - request.events.completed$.subscribe(() => { - logDebugMessage('completed$ subscription trigger.'); - shouldStop = true; - }); - - const { end, push, responseWithHeaders } = streamFactory( - request.headers, - logger, - request.body.compressResponse - ); - - const entities = [ - 'kimchy', - 's1monw', - 'martijnvg', - 'jasontedor', - 'nik9000', - 'javanna', - 'rjernst', - 'jrodewig', - ]; - - const actions = [...Array(19).fill('add'), 'delete']; - - if (simulateError) { - actions.push('throw-error'); - actions.push('emit-error'); - } - - let progress = 0; - - async function pushStreamUpdate() { - setTimeout(() => { - try { - progress++; - - if (progress > 100 || shouldStop) { - end(); - return; + async (context, request, response) => { + const maxTimeoutMs = request.body.timeout ?? 250; + const simulateError = request.body.simulateErrors ?? false; + + let logMessageCounter = 1; + + function logDebugMessage(msg: string) { + logger.debug(`Response Stream Example #${logMessageCounter}: ${msg}`); + logMessageCounter++; + } + + logDebugMessage('Starting stream.'); + + let shouldStop = false; + request.events.aborted$.subscribe(() => { + logDebugMessage('aborted$ subscription trigger.'); + shouldStop = true; + }); + request.events.completed$.subscribe(() => { + logDebugMessage('completed$ subscription trigger.'); + shouldStop = true; + }); + + const { end, push, responseWithHeaders } = streamFactory( + request.headers, + logger, + request.body.compressResponse + ); + + const entities = [ + 'kimchy', + 's1monw', + 'martijnvg', + 'jasontedor', + 'nik9000', + 'javanna', + 'rjernst', + 'jrodewig', + ]; + + const actions = [...Array(19).fill('add'), 'delete']; + + if (simulateError) { + actions.push('throw-error'); + actions.push('emit-error'); + } + + let progress = 0; + + async function pushStreamUpdate() { + setTimeout(() => { + try { + progress++; + + if (progress > 100 || shouldStop) { + end(); + return; + } + + push(updateProgressAction(progress)); + + const randomEntity = entities[Math.floor(Math.random() * entities.length)]; + const randomAction = actions[Math.floor(Math.random() * actions.length)]; + + if (randomAction === 'add') { + const randomCommits = Math.floor(Math.random() * 100); + push(addToEntityAction(randomEntity, randomCommits)); + } else if (randomAction === 'delete') { + push(deleteEntityAction(randomEntity)); + } else if (randomAction === 'throw-error') { + // Throw an error. It should not crash Kibana! + // It should be caught and logged to the Kibana server console. + throw new Error('There was a (simulated) server side error!'); + } else if (randomAction === 'emit-error') { + // Emit an error as a stream action. + push(errorAction('(Simulated) error pushed to the stream')); + return; + } + + pushStreamUpdate(); + } catch (e) { + logger.error(e); } + }, Math.floor(Math.random() * maxTimeoutMs)); + } - push(updateProgressAction(progress)); - - const randomEntity = entities[Math.floor(Math.random() * entities.length)]; - const randomAction = actions[Math.floor(Math.random() * actions.length)]; - - if (randomAction === 'add') { - const randomCommits = Math.floor(Math.random() * 100); - push(addToEntityAction(randomEntity, randomCommits)); - } else if (randomAction === 'delete') { - push(deleteEntityAction(randomEntity)); - } else if (randomAction === 'throw-error') { - // Throw an error. It should not crash Kibana! - // It should be caught and logged to the Kibana server console. - throw new Error('There was a (simulated) server side error!'); - } else if (randomAction === 'emit-error') { - // Emit an error as a stream action. - push(errorAction('(Simulated) error pushed to the stream')); - return; - } + // do not call this using `await` so it will run asynchronously while we return the stream already. + pushStreamUpdate(); - pushStreamUpdate(); - } catch (e) { - logger.error(e); - } - }, Math.floor(Math.random() * maxTimeoutMs)); + return response.ok(responseWithHeaders); } - - // do not call this using `await` so it will run asynchronously while we return the stream already. - pushStreamUpdate(); - - return response.ok(responseWithHeaders); - } - ); + ); }; diff --git a/examples/response_stream/server/routes/single_string_stream.ts b/examples/response_stream/server/routes/single_string_stream.ts index fde4947746dbf..ee55cf3b0bc8e 100644 --- a/examples/response_stream/server/routes/single_string_stream.ts +++ b/examples/response_stream/server/routes/single_string_stream.ts @@ -17,63 +17,70 @@ function timeout(ms: number) { } export const defineSimpleStringStreamRoute = (router: IRouter, logger: Logger) => { - router.post( - { + router.versioned + .post({ path: API_ENDPOINT.SIMPLE_STRING_STREAM, - validate: { - body: simpleStringStreamRequestBodySchema, + access: 'internal', + }) + .addVersion( + { + version: '1', + validate: { + request: { + body: simpleStringStreamRequestBodySchema, + }, + }, }, - }, - async (context, request, response) => { - const maxTimeoutMs = request.body.timeout ?? 250; + async (context, request, response) => { + const maxTimeoutMs = request.body.timeout ?? 250; - let shouldStop = false; - request.events.aborted$.subscribe(() => { - shouldStop = true; - }); - request.events.completed$.subscribe(() => { - shouldStop = true; - }); + let shouldStop = false; + request.events.aborted$.subscribe(() => { + shouldStop = true; + }); + request.events.completed$.subscribe(() => { + shouldStop = true; + }); - const { end, push, responseWithHeaders } = streamFactory( - request.headers, - logger, - request.body.compressResponse - ); + const { end, push, responseWithHeaders } = streamFactory( + request.headers, + logger, + request.body.compressResponse + ); - const text = - 'Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. Elasticsearch is developed in Java and is dual-licensed under the source-available Server Side Public License and the Elastic license, while other parts fall under the proprietary (source-available) Elastic License. Official clients are available in Java, .NET (C#), PHP, Python, Apache Groovy, Ruby and many other languages. According to the DB-Engines ranking, Elasticsearch is the most popular enterprise search engine.'; + const text = + 'Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents. Elasticsearch is developed in Java and is dual-licensed under the source-available Server Side Public License and the Elastic license, while other parts fall under the proprietary (source-available) Elastic License. Official clients are available in Java, .NET (C#), PHP, Python, Apache Groovy, Ruby and many other languages. According to the DB-Engines ranking, Elasticsearch is the most popular enterprise search engine.'; - const tokens = text.split(' '); + const tokens = text.split(' '); - async function pushStreamUpdate() { - try { - if (shouldStop) { - end(); - return; - } + async function pushStreamUpdate() { + try { + if (shouldStop) { + end(); + return; + } - const token = tokens.shift(); + const token = tokens.shift(); - if (token !== undefined) { - push(`${token} `); - await timeout(Math.floor(Math.random() * maxTimeoutMs)); + if (token !== undefined) { + push(`${token} `); + await timeout(Math.floor(Math.random() * maxTimeoutMs)); - if (!shouldStop) { - pushStreamUpdate(); + if (!shouldStop) { + pushStreamUpdate(); + } + } else { + end(); } - } else { - end(); + } catch (e) { + logger.error(`There was an error: ${e.toString()}`); } - } catch (e) { - logger.error(`There was an error: ${e.toString()}`); } - } - // do not call this using `await` so it will run asynchronously while we return the stream already. - pushStreamUpdate(); + // do not call this using `await` so it will run asynchronously while we return the stream already. + pushStreamUpdate(); - return response.ok(responseWithHeaders); - } - ); + return response.ok(responseWithHeaders); + } + ); }; diff --git a/x-pack/packages/ml/aiops_utils/src/fetch_stream.ts b/x-pack/packages/ml/aiops_utils/src/fetch_stream.ts index d8d71adc81bc3..d52ffcbf1a6d1 100644 --- a/x-pack/packages/ml/aiops_utils/src/fetch_stream.ts +++ b/x-pack/packages/ml/aiops_utils/src/fetch_stream.ts @@ -7,6 +7,8 @@ import type { ReducerAction } from 'react'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; + import type { UseFetchStreamParamsDefault } from './use_fetch_stream'; type GeneratorError = string | null; @@ -23,6 +25,7 @@ type GeneratorError = string | null; * ``` * * @param endpoint — The API endpoint including the Kibana basepath. + * @param apiVersion - The API version to be used. * @param abortCtrl — Abort controller for cancelling the request. * @param body — The request body. For now all requests are POST. * @param ndjson — Boolean flag to receive the stream as a raw string or NDJSON. @@ -37,6 +40,7 @@ type GeneratorError = string | null; */ export async function* fetchStream( endpoint: `${BasePath}${I['endpoint']}`, + apiVersion: string, abortCtrl: React.MutableRefObject, body: I['body'], ndjson = true, @@ -54,6 +58,7 @@ export async function* fetchStream 0 ? { body: JSON.stringify(body) } : {}), diff --git a/x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts b/x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts index 7402161db64a1..cbfb5d6626586 100644 --- a/x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts +++ b/x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts @@ -7,11 +7,31 @@ /** * Time range definition for baseline and deviation to be used by spike log analysis. + * + * @export + * @interface WindowParameters + * @typedef {WindowParameters} */ export interface WindowParameters { + /** + * Baseline minimum value + * @type {number} + */ baselineMin: number; + /** + * Baseline maximum value + * @type {number} + */ baselineMax: number; + /** + * Deviation minimum value + * @type {number} + */ deviationMin: number; + /** + * Deviation maximum value + * @type {number} + */ deviationMax: number; } diff --git a/x-pack/packages/ml/aiops_utils/src/use_fetch_stream.ts b/x-pack/packages/ml/aiops_utils/src/use_fetch_stream.ts index 516a63e165ffb..e5e8edc136ae8 100644 --- a/x-pack/packages/ml/aiops_utils/src/use_fetch_stream.ts +++ b/x-pack/packages/ml/aiops_utils/src/use_fetch_stream.ts @@ -21,10 +21,31 @@ import { stringReducer, StringReducer } from './string_reducer'; /** * Custom hook type definition of the base params for an NDJSON stream with custom reducer. + * + * @export + * @interface UseFetchStreamCustomReducerParams + * @typedef {UseFetchStreamCustomReducerParams} */ export interface UseFetchStreamCustomReducerParams { + /** + * API endpoint + * @type {string} + */ endpoint: string; + /** + * API version + * @type {string} + */ + apiVersion: string; + /** + * Request body + * @type {object} + */ body: object; + /** + * Reducer function to be applied to response chunks. + * @type {Reducer} + */ reducer: Reducer; } @@ -32,11 +53,36 @@ export interface UseFetchStreamCustomReducerParams { * Custom hook type definition of the base params for a string base stream without a custom reducer. */ export interface UseFetchStreamParamsDefault { + /** + * API endpoint + * @type {string} + */ endpoint: string; + /** + * API version + * @type {string} + */ + apiVersion: string; + /** + * Request body + * @type {object} + */ body: object; + /** + * Reducer function to be applied to response chunks. + * @type {StringReducer} + */ reducer: StringReducer; } +/** + * The return type of the `useFetchStream` hook. + * + * @interface UseFetchStreamReturnType + * @typedef {UseFetchStreamReturnType} + * @template Data + * @template Action + */ interface UseFetchStreamReturnType { cancel: () => void; data: Data; @@ -47,34 +93,83 @@ interface UseFetchStreamReturnType { start: () => Promise; } -// These overloads allow us to fall back to a simple reducer that just acts on a string as the reducer state -// if no options are supplied. Passing in options will use a custom reducer with appropriate type support. +/** + * This overload allows us to fall back to a simple reducer that + * just acts on a string as the reducer state if no options are supplied. + * + * @export + * @template I + * @template BasePath + * @param {`${I['endpoint']}`} endpoint - API endpoint including Kibana base path. + * @param {I['apiVersion']} apiVersion - API version. + * @param {I['body']} body - API request body. + * @returns {UseFetchStreamReturnType>} - An object with streaming data and methods to act on the stream. + */ export function useFetchStream( endpoint: `${BasePath}${I['endpoint']}`, + apiVersion: I['apiVersion'], body: I['body'] ): UseFetchStreamReturnType>; +/** + * This overload covers passing in options and will use + * a custom reducer with appropriate type support. + * + * @export + * @template I + * @template BasePath + * @param {`${I['endpoint']}`} endpoint - API endpoint including Kibana base path. + * @param {I['apiVersion']} apiVersion - API version. + * @param {I['body']} body - API request body. + * @param {{ reducer: I['reducer']; initialState: ReducerState }} options - Custom reducer and initial state. + * @returns {UseFetchStreamReturnType, ReducerAction>} - An object with streaming data and methods to act on the stream. + */ export function useFetchStream< I extends UseFetchStreamCustomReducerParams, BasePath extends string >( endpoint: `${BasePath}${I['endpoint']}`, + apiVersion: I['apiVersion'], body: I['body'], - options: { reducer: I['reducer']; initialState: ReducerState } + options: { + /** + * Custom reducer + * @type {I['reducer']} + */ + reducer: I['reducer']; + /** + * Initial state + * @type {ReducerState} + */ + initialState: ReducerState; + } ): UseFetchStreamReturnType, ReducerAction>; /** * Custom hook to receive streaming data. * * @param endpoint - API endpoint including Kibana base path. + * @param apiVersion - API version. * @param body - API request body. * @param options - Optional custom reducer and initial state. - * @returns An object with streaming data and methods act on the stream. + * @returns An object with streaming data and methods to act on the stream. */ export function useFetchStream( endpoint: `${BasePath}${I['endpoint']}`, + apiVersion: string, body: I['body'], - options?: { reducer: I['reducer']; initialState: ReducerState } + options?: { + /** + * Custom reducer + * @type {I['reducer']} + */ + reducer: I['reducer']; + /** + * Initial state + * @type {ReducerState} + */ + initialState: ReducerState; + } ): UseFetchStreamReturnType, ReducerAction> { const [errors, setErrors] = useState([]); const [isCancelled, setIsCancelled] = useState(false); @@ -106,7 +201,7 @@ export function useFetchStream(endpoint, abortCtrl, body, options !== undefined)) { + >(endpoint, apiVersion, abortCtrl, body, options !== undefined)) { if (fetchStreamError !== null) { addError(fetchStreamError); } else if (actions.length > 0) { diff --git a/x-pack/packages/ml/aiops_utils/tsconfig.json b/x-pack/packages/ml/aiops_utils/tsconfig.json index 727c591601218..a548e35816a38 100644 --- a/x-pack/packages/ml/aiops_utils/tsconfig.json +++ b/x-pack/packages/ml/aiops_utils/tsconfig.json @@ -16,6 +16,7 @@ "kbn_references": [ "@kbn/logging", "@kbn/core-http-server", + "@kbn/core-http-common", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/aiops/common/api/index.ts b/x-pack/plugins/aiops/common/api/index.ts index 2397f554c128f..f1f57fea9742e 100644 --- a/x-pack/plugins/aiops/common/api/index.ts +++ b/x-pack/plugins/aiops/common/api/index.ts @@ -17,6 +17,7 @@ export const API_ENDPOINT = { export interface ApiExplainLogRateSpikes { endpoint: typeof API_ENDPOINT.EXPLAIN_LOG_RATE_SPIKES; + apiVersion: string; reducer: typeof streamReducer; body: AiopsExplainLogRateSpikesSchema; actions: AiopsExplainLogRateSpikesApiAction; diff --git a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_analysis.tsx b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_analysis.tsx index 4287048628b8c..d5a9caeebd551 100644 --- a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_analysis.tsx +++ b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_analysis.tsx @@ -139,6 +139,7 @@ export const ExplainLogRateSpikesAnalysis: FC errors: streamErrors, } = useFetchStream( `${basePath}/internal/aiops/explain_log_rate_spikes`, + '1', { start: earliest, end: latest, diff --git a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts index 787071d1e33d8..03732369b0bb9 100644 --- a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts +++ b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts @@ -69,624 +69,633 @@ export const defineExplainLogRateSpikesRoute = ( logger: Logger, coreStart: CoreStart ) => { - router.post( - { + router.versioned + .post({ path: API_ENDPOINT.EXPLAIN_LOG_RATE_SPIKES, - validate: { - body: aiopsExplainLogRateSpikesSchema, + access: 'internal', + }) + .addVersion( + { + version: '1', + validate: { + request: { + body: aiopsExplainLogRateSpikesSchema, + }, + }, }, - }, - async (context, request, response) => { - if (!license.isActivePlatinumLicense) { - return response.forbidden(); - } - - const client = (await context.core).elasticsearch.client.asCurrentUser; - const executionContext = createExecutionContext(coreStart, PLUGIN_ID, request.route.path); - - return await coreStart.executionContext.withContext(executionContext, () => { - let logMessageCounter = 1; - - function logDebugMessage(msg: string) { - logger.debug(`Explain Log Rate Spikes #${logMessageCounter}: ${msg}`); - logMessageCounter++; + async (context, request, response) => { + if (!license.isActivePlatinumLicense) { + return response.forbidden(); } - logDebugMessage('Starting analysis.'); + const client = (await context.core).elasticsearch.client.asCurrentUser; + const executionContext = createExecutionContext(coreStart, PLUGIN_ID, request.route.path); - const groupingEnabled = !!request.body.grouping; - const sampleProbability = request.body.sampleProbability ?? 1; + return await coreStart.executionContext.withContext(executionContext, () => { + let logMessageCounter = 1; - const controller = new AbortController(); - const abortSignal = controller.signal; + function logDebugMessage(msg: string) { + logger.debug(`Explain Log Rate Spikes #${logMessageCounter}: ${msg}`); + logMessageCounter++; + } - let isRunning = false; - let loaded = 0; - let shouldStop = false; - request.events.aborted$.subscribe(() => { - logDebugMessage('aborted$ subscription trigger.'); - shouldStop = true; - controller.abort(); - }); - request.events.completed$.subscribe(() => { - logDebugMessage('completed$ subscription trigger.'); - shouldStop = true; - controller.abort(); - }); + logDebugMessage('Starting analysis.'); + + const groupingEnabled = !!request.body.grouping; + const sampleProbability = request.body.sampleProbability ?? 1; + + const controller = new AbortController(); + const abortSignal = controller.signal; + + let isRunning = false; + let loaded = 0; + let shouldStop = false; + request.events.aborted$.subscribe(() => { + logDebugMessage('aborted$ subscription trigger.'); + shouldStop = true; + controller.abort(); + }); + request.events.completed$.subscribe(() => { + logDebugMessage('completed$ subscription trigger.'); + shouldStop = true; + controller.abort(); + }); + + const { + end: streamEnd, + push, + responseWithHeaders, + } = streamFactory( + request.headers, + logger, + request.body.compressResponse, + request.body.flushFix + ); + + function pushPingWithTimeout() { + setTimeout(() => { + if (isRunning) { + logDebugMessage('Ping message.'); + push(pingAction()); + pushPingWithTimeout(); + } + }, PING_FREQUENCY); + } - const { - end: streamEnd, - push, - responseWithHeaders, - } = streamFactory( - request.headers, - logger, - request.body.compressResponse, - request.body.flushFix - ); - - function pushPingWithTimeout() { - setTimeout(() => { + function end() { if (isRunning) { - logDebugMessage('Ping message.'); - push(pingAction()); - pushPingWithTimeout(); + isRunning = false; + logDebugMessage('Ending analysis.'); + streamEnd(); + } else { + logDebugMessage('end() was called again with isRunning already being false.'); } - }, PING_FREQUENCY); - } - - function end() { - if (isRunning) { - isRunning = false; - logDebugMessage('Ending analysis.'); - streamEnd(); - } else { - logDebugMessage('end() was called again with isRunning already being false.'); } - } - - function endWithUpdatedLoadingState() { - push( - updateLoadingStateAction({ - ccsWarning: false, - loaded: 1, - loadingState: i18n.translate( - 'xpack.aiops.explainLogRateSpikes.loadingState.doneMessage', - { - defaultMessage: 'Done.', - } - ), - }) - ); - end(); - } + function endWithUpdatedLoadingState() { + push( + updateLoadingStateAction({ + ccsWarning: false, + loaded: 1, + loadingState: i18n.translate( + 'xpack.aiops.explainLogRateSpikes.loadingState.doneMessage', + { + defaultMessage: 'Done.', + } + ), + }) + ); - function pushError(m: string) { - logDebugMessage('Push error.'); - push(addErrorAction(m)); - } + end(); + } - async function runAnalysis() { - try { - isRunning = true; + function pushError(m: string) { + logDebugMessage('Push error.'); + push(addErrorAction(m)); + } - if (!request.body.overrides) { - logDebugMessage('Full Reset.'); - push(resetAllAction()); - } else { - logDebugMessage('Reset Errors.'); - push(resetErrorsAction()); - } + async function runAnalysis() { + try { + isRunning = true; + + if (!request.body.overrides) { + logDebugMessage('Full Reset.'); + push(resetAllAction()); + } else { + logDebugMessage('Reset Errors.'); + push(resetErrorsAction()); + } - if (request.body.overrides?.regroupOnly) { - logDebugMessage('Reset Groups.'); - push(resetGroupsAction()); - } + if (request.body.overrides?.regroupOnly) { + logDebugMessage('Reset Groups.'); + push(resetGroupsAction()); + } - if (request.body.overrides?.loaded) { - logDebugMessage(`Set 'loaded' override to '${request.body.overrides?.loaded}'.`); - loaded = request.body.overrides?.loaded; - } + if (request.body.overrides?.loaded) { + logDebugMessage(`Set 'loaded' override to '${request.body.overrides?.loaded}'.`); + loaded = request.body.overrides?.loaded; + } - pushPingWithTimeout(); + pushPingWithTimeout(); - // Step 1: Index Info: Field candidates, total doc count, sample probability + // Step 1: Index Info: Field candidates, total doc count, sample probability - const fieldCandidates: Awaited>['fieldCandidates'] = - []; - let fieldCandidatesCount = fieldCandidates.length; + const fieldCandidates: Awaited>['fieldCandidates'] = + []; + let fieldCandidatesCount = fieldCandidates.length; - let totalDocCount = 0; + let totalDocCount = 0; - if (!request.body.overrides?.remainingFieldCandidates) { - logDebugMessage('Fetch index information.'); - push( - updateLoadingStateAction({ - ccsWarning: false, - loaded, - loadingState: i18n.translate( - 'xpack.aiops.explainLogRateSpikes.loadingState.loadingIndexInformation', - { - defaultMessage: 'Loading index information.', - } - ), - }) - ); + if (!request.body.overrides?.remainingFieldCandidates) { + logDebugMessage('Fetch index information.'); + push( + updateLoadingStateAction({ + ccsWarning: false, + loaded, + loadingState: i18n.translate( + 'xpack.aiops.explainLogRateSpikes.loadingState.loadingIndexInformation', + { + defaultMessage: 'Loading index information.', + } + ), + }) + ); - try { - const indexInfo = await fetchIndexInfo(client, request.body, abortSignal); - fieldCandidates.push(...indexInfo.fieldCandidates); - fieldCandidatesCount = fieldCandidates.length; - totalDocCount = indexInfo.totalDocCount; - } catch (e) { - if (!isRequestAbortedError(e)) { - logger.error(`Failed to fetch index information, got: \n${e.toString()}`); - pushError(`Failed to fetch index information.`); + try { + const indexInfo = await fetchIndexInfo(client, request.body, abortSignal); + fieldCandidates.push(...indexInfo.fieldCandidates); + fieldCandidatesCount = fieldCandidates.length; + totalDocCount = indexInfo.totalDocCount; + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error(`Failed to fetch index information, got: \n${e.toString()}`); + pushError(`Failed to fetch index information.`); + } + end(); + return; } - end(); - return; - } - logDebugMessage(`Total document count: ${totalDocCount}`); - logDebugMessage(`Sample probability: ${sampleProbability}`); + logDebugMessage(`Total document count: ${totalDocCount}`); + logDebugMessage(`Sample probability: ${sampleProbability}`); - loaded += LOADED_FIELD_CANDIDATES; + loaded += LOADED_FIELD_CANDIDATES; - pushPingWithTimeout(); + pushPingWithTimeout(); - push( - updateLoadingStateAction({ - ccsWarning: false, - loaded, - loadingState: i18n.translate( - 'xpack.aiops.explainLogRateSpikes.loadingState.identifiedFieldCandidates', - { - defaultMessage: - 'Identified {fieldCandidatesCount, plural, one {# field candidate} other {# field candidates}}.', - values: { - fieldCandidatesCount, - }, - } - ), - }) - ); + push( + updateLoadingStateAction({ + ccsWarning: false, + loaded, + loadingState: i18n.translate( + 'xpack.aiops.explainLogRateSpikes.loadingState.identifiedFieldCandidates', + { + defaultMessage: + 'Identified {fieldCandidatesCount, plural, one {# field candidate} other {# field candidates}}.', + values: { + fieldCandidatesCount, + }, + } + ), + }) + ); - if (fieldCandidatesCount === 0) { - endWithUpdatedLoadingState(); - } else if (shouldStop) { - logDebugMessage('shouldStop after fetching field candidates.'); - end(); - return; + if (fieldCandidatesCount === 0) { + endWithUpdatedLoadingState(); + } else if (shouldStop) { + logDebugMessage('shouldStop after fetching field candidates.'); + end(); + return; + } } - } - // Step 2: Significant Terms + // Step 2: Significant Terms - const significantTerms: SignificantTerm[] = request.body.overrides?.significantTerms - ? request.body.overrides?.significantTerms - : []; - const fieldsToSample = new Set(); + const significantTerms: SignificantTerm[] = request.body.overrides?.significantTerms + ? request.body.overrides?.significantTerms + : []; + const fieldsToSample = new Set(); - // Don't use more than 10 here otherwise Kibana will emit an error - // regarding a limit of abort signal listeners of more than 10. - const MAX_CONCURRENT_QUERIES = 10; + // Don't use more than 10 here otherwise Kibana will emit an error + // regarding a limit of abort signal listeners of more than 10. + const MAX_CONCURRENT_QUERIES = 10; - let remainingFieldCandidates: string[]; - let loadingStepSizePValues = PROGRESS_STEP_P_VALUES; + let remainingFieldCandidates: string[]; + let loadingStepSizePValues = PROGRESS_STEP_P_VALUES; - if (request.body.overrides?.remainingFieldCandidates) { - fieldCandidates.push(...request.body.overrides?.remainingFieldCandidates); - remainingFieldCandidates = request.body.overrides?.remainingFieldCandidates; - fieldCandidatesCount = fieldCandidates.length; - loadingStepSizePValues = - LOADED_FIELD_CANDIDATES + - PROGRESS_STEP_P_VALUES - - (request.body.overrides?.loaded ?? PROGRESS_STEP_P_VALUES); - } else { - remainingFieldCandidates = fieldCandidates; - } + if (request.body.overrides?.remainingFieldCandidates) { + fieldCandidates.push(...request.body.overrides?.remainingFieldCandidates); + remainingFieldCandidates = request.body.overrides?.remainingFieldCandidates; + fieldCandidatesCount = fieldCandidates.length; + loadingStepSizePValues = + LOADED_FIELD_CANDIDATES + + PROGRESS_STEP_P_VALUES - + (request.body.overrides?.loaded ?? PROGRESS_STEP_P_VALUES); + } else { + remainingFieldCandidates = fieldCandidates; + } - logDebugMessage('Fetch p-values.'); + logDebugMessage('Fetch p-values.'); - const pValuesQueue = queue(async function (fieldCandidate: string) { - loaded += (1 / fieldCandidatesCount) * loadingStepSizePValues; + const pValuesQueue = queue(async function (fieldCandidate: string) { + loaded += (1 / fieldCandidatesCount) * loadingStepSizePValues; - let pValues: Awaited>; + let pValues: Awaited>; - try { - pValues = await fetchSignificantTermPValues( - client, - request.body, - [fieldCandidate], - logger, - sampleProbability, - pushError, - abortSignal - ); - } catch (e) { - if (!isRequestAbortedError(e)) { - logger.error( - `Failed to fetch p-values for '${fieldCandidate}', got: \n${e.toString()}` + try { + pValues = await fetchSignificantTermPValues( + client, + request.body, + [fieldCandidate], + logger, + sampleProbability, + pushError, + abortSignal ); - pushError(`Failed to fetch p-values for '${fieldCandidate}'.`); + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to fetch p-values for '${fieldCandidate}', got: \n${e.toString()}` + ); + pushError(`Failed to fetch p-values for '${fieldCandidate}'.`); + } + return; } - return; - } - remainingFieldCandidates = remainingFieldCandidates.filter( - (d) => d !== fieldCandidate - ); + remainingFieldCandidates = remainingFieldCandidates.filter( + (d) => d !== fieldCandidate + ); - if (pValues.length > 0) { - pValues.forEach((d) => { - fieldsToSample.add(d.fieldName); - }); - significantTerms.push(...pValues); + if (pValues.length > 0) { + pValues.forEach((d) => { + fieldsToSample.add(d.fieldName); + }); + significantTerms.push(...pValues); - push(addSignificantTermsAction(pValues)); - } + push(addSignificantTermsAction(pValues)); + } - push( - updateLoadingStateAction({ - ccsWarning: false, - loaded, - loadingState: i18n.translate( - 'xpack.aiops.explainLogRateSpikes.loadingState.identifiedFieldValuePairs', - { - defaultMessage: - 'Identified {fieldValuePairsCount, plural, one {# significant field/value pair} other {# significant field/value pairs}}.', - values: { - fieldValuePairsCount: significantTerms.length, - }, - } - ), - remainingFieldCandidates, - }) - ); - }, MAX_CONCURRENT_QUERIES); - - pValuesQueue.push(fieldCandidates, (err) => { - if (err) { - logger.error(`Failed to fetch p-values.', got: \n${err.toString()}`); - pushError(`Failed to fetch p-values.`); - pValuesQueue.kill(); - end(); - } else if (shouldStop) { - logDebugMessage('shouldStop fetching p-values.'); - pValuesQueue.kill(); - end(); - } - }); - await pValuesQueue.drain(); + push( + updateLoadingStateAction({ + ccsWarning: false, + loaded, + loadingState: i18n.translate( + 'xpack.aiops.explainLogRateSpikes.loadingState.identifiedFieldValuePairs', + { + defaultMessage: + 'Identified {fieldValuePairsCount, plural, one {# significant field/value pair} other {# significant field/value pairs}}.', + values: { + fieldValuePairsCount: significantTerms.length, + }, + } + ), + remainingFieldCandidates, + }) + ); + }, MAX_CONCURRENT_QUERIES); - if (significantTerms.length === 0) { - logDebugMessage('Stopping analysis, did not find significant terms.'); - endWithUpdatedLoadingState(); - return; - } + pValuesQueue.push(fieldCandidates, (err) => { + if (err) { + logger.error(`Failed to fetch p-values.', got: \n${err.toString()}`); + pushError(`Failed to fetch p-values.`); + pValuesQueue.kill(); + end(); + } else if (shouldStop) { + logDebugMessage('shouldStop fetching p-values.'); + pValuesQueue.kill(); + end(); + } + }); + await pValuesQueue.drain(); - const histogramFields: [NumericHistogramField] = [ - { fieldName: request.body.timeFieldName, type: KBN_FIELD_TYPES.DATE }, - ]; + if (significantTerms.length === 0) { + logDebugMessage('Stopping analysis, did not find significant terms.'); + endWithUpdatedLoadingState(); + return; + } - logDebugMessage('Fetch overall histogram.'); + const histogramFields: [NumericHistogramField] = [ + { fieldName: request.body.timeFieldName, type: KBN_FIELD_TYPES.DATE }, + ]; - let overallTimeSeries: NumericChartData | undefined; + logDebugMessage('Fetch overall histogram.'); - const overallHistogramQuery = getHistogramQuery(request.body); + let overallTimeSeries: NumericChartData | undefined; - try { - overallTimeSeries = ( - (await fetchHistogramsForFields( - client, - request.body.index, - overallHistogramQuery, - // fields - histogramFields, - // samplerShardSize - -1, - undefined, - abortSignal, - sampleProbability, - RANDOM_SAMPLER_SEED - )) as [NumericChartData] - )[0]; - } catch (e) { - if (!isRequestAbortedError(e)) { - logger.error(`Failed to fetch the overall histogram data, got: \n${e.toString()}`); - pushError(`Failed to fetch overall histogram data.`); + const overallHistogramQuery = getHistogramQuery(request.body); + + try { + overallTimeSeries = ( + (await fetchHistogramsForFields( + client, + request.body.index, + overallHistogramQuery, + // fields + histogramFields, + // samplerShardSize + -1, + undefined, + abortSignal, + sampleProbability, + RANDOM_SAMPLER_SEED + )) as [NumericChartData] + )[0]; + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to fetch the overall histogram data, got: \n${e.toString()}` + ); + pushError(`Failed to fetch overall histogram data.`); + } + // Still continue the analysis even if loading the overall histogram fails. } - // Still continue the analysis even if loading the overall histogram fails. - } - function pushHistogramDataLoadingState() { - push( - updateLoadingStateAction({ - ccsWarning: false, - loaded, - loadingState: i18n.translate( - 'xpack.aiops.explainLogRateSpikes.loadingState.loadingHistogramData', - { - defaultMessage: 'Loading histogram data.', - } - ), - }) - ); - } + function pushHistogramDataLoadingState() { + push( + updateLoadingStateAction({ + ccsWarning: false, + loaded, + loadingState: i18n.translate( + 'xpack.aiops.explainLogRateSpikes.loadingState.loadingHistogramData', + { + defaultMessage: 'Loading histogram data.', + } + ), + }) + ); + } - if (shouldStop) { - logDebugMessage('shouldStop after fetching overall histogram.'); - end(); - return; - } + if (shouldStop) { + logDebugMessage('shouldStop after fetching overall histogram.'); + end(); + return; + } - if (groupingEnabled) { - logDebugMessage('Group results.'); - - push( - updateLoadingStateAction({ - ccsWarning: false, - loaded, - loadingState: i18n.translate( - 'xpack.aiops.explainLogRateSpikes.loadingState.groupingResults', - { - defaultMessage: 'Transforming significant field/value pairs into groups.', - } - ), - groupsMissing: true, - }) - ); + if (groupingEnabled) { + logDebugMessage('Group results.'); - try { - const { fields, df } = await fetchFrequentItemSets( - client, - request.body.index, - JSON.parse(request.body.searchQuery) as estypes.QueryDslQueryContainer, - significantTerms, - request.body.timeFieldName, - request.body.deviationMin, - request.body.deviationMax, - logger, - sampleProbability, - pushError, - abortSignal + push( + updateLoadingStateAction({ + ccsWarning: false, + loaded, + loadingState: i18n.translate( + 'xpack.aiops.explainLogRateSpikes.loadingState.groupingResults', + { + defaultMessage: 'Transforming significant field/value pairs into groups.', + } + ), + groupsMissing: true, + }) ); - if (shouldStop) { - logDebugMessage('shouldStop after fetching frequent_item_sets.'); - end(); - return; - } - - if (fields.length > 0 && df.length > 0) { - const significantTermGroups = getSignificantTermGroups( - df, + try { + const { fields, df } = await fetchFrequentItemSets( + client, + request.body.index, + JSON.parse(request.body.searchQuery) as estypes.QueryDslQueryContainer, significantTerms, - fields + request.body.timeFieldName, + request.body.deviationMin, + request.body.deviationMax, + logger, + sampleProbability, + pushError, + abortSignal ); - // We'll find out if there's at least one group with at least two items, - // only then will we return the groups to the clients and make the grouping option available. - const maxItems = Math.max(...significantTermGroups.map((g) => g.group.length)); - - if (maxItems > 1) { - push(addSignificantTermsGroupAction(significantTermGroups)); - } - - loaded += PROGRESS_STEP_GROUPING; - - pushHistogramDataLoadingState(); - if (shouldStop) { - logDebugMessage('shouldStop after grouping.'); + logDebugMessage('shouldStop after fetching frequent_item_sets.'); end(); return; } - logDebugMessage(`Fetch ${significantTermGroups.length} group histograms.`); + if (fields.length > 0 && df.length > 0) { + const significantTermGroups = getSignificantTermGroups( + df, + significantTerms, + fields + ); + + // We'll find out if there's at least one group with at least two items, + // only then will we return the groups to the clients and make the grouping option available. + const maxItems = Math.max(...significantTermGroups.map((g) => g.group.length)); + + if (maxItems > 1) { + push(addSignificantTermsGroupAction(significantTermGroups)); + } + + loaded += PROGRESS_STEP_GROUPING; + + pushHistogramDataLoadingState(); - const groupHistogramQueue = queue(async function (cpg: SignificantTermGroup) { if (shouldStop) { - logDebugMessage('shouldStop abort fetching group histograms.'); - groupHistogramQueue.kill(); + logDebugMessage('shouldStop after grouping.'); end(); return; } - if (overallTimeSeries !== undefined) { - const histogramQuery = getHistogramQuery(request.body, getGroupFilter(cpg)); - - let cpgTimeSeries: NumericChartData; - try { - cpgTimeSeries = ( - (await fetchHistogramsForFields( - client, - request.body.index, - histogramQuery, - // fields - [ - { - fieldName: request.body.timeFieldName, - type: KBN_FIELD_TYPES.DATE, - interval: overallTimeSeries.interval, - min: overallTimeSeries.stats[0], - max: overallTimeSeries.stats[1], - }, - ], - // samplerShardSize - -1, - undefined, - abortSignal, - sampleProbability, - RANDOM_SAMPLER_SEED - )) as [NumericChartData] - )[0]; - } catch (e) { - if (!isRequestAbortedError(e)) { - logger.error( - `Failed to fetch the histogram data for group #${ - cpg.id - }, got: \n${e.toString()}` - ); - pushError(`Failed to fetch the histogram data for group #${cpg.id}.`); - } + logDebugMessage(`Fetch ${significantTermGroups.length} group histograms.`); + + const groupHistogramQueue = queue(async function (cpg: SignificantTermGroup) { + if (shouldStop) { + logDebugMessage('shouldStop abort fetching group histograms.'); + groupHistogramQueue.kill(); + end(); return; } - const histogram = - overallTimeSeries.data.map((o, i) => { - const current = cpgTimeSeries.data.find( - (d1) => d1.key_as_string === o.key_as_string - ) ?? { - doc_count: 0, - }; - return { - key: o.key, - key_as_string: o.key_as_string ?? '', - doc_count_significant_term: current.doc_count, - doc_count_overall: Math.max(0, o.doc_count - current.doc_count), - }; - }) ?? []; - - push( - addSignificantTermsGroupHistogramAction([ - { - id: cpg.id, - histogram, - }, - ]) - ); - } - }, MAX_CONCURRENT_QUERIES); - groupHistogramQueue.push(significantTermGroups); - await groupHistogramQueue.drain(); - } - } catch (e) { - if (!isRequestAbortedError(e)) { - logger.error( - `Failed to transform field/value pairs into groups, got: \n${e.toString()}` - ); - pushError(`Failed to transform field/value pairs into groups.`); + if (overallTimeSeries !== undefined) { + const histogramQuery = getHistogramQuery(request.body, getGroupFilter(cpg)); + + let cpgTimeSeries: NumericChartData; + try { + cpgTimeSeries = ( + (await fetchHistogramsForFields( + client, + request.body.index, + histogramQuery, + // fields + [ + { + fieldName: request.body.timeFieldName, + type: KBN_FIELD_TYPES.DATE, + interval: overallTimeSeries.interval, + min: overallTimeSeries.stats[0], + max: overallTimeSeries.stats[1], + }, + ], + // samplerShardSize + -1, + undefined, + abortSignal, + sampleProbability, + RANDOM_SAMPLER_SEED + )) as [NumericChartData] + )[0]; + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to fetch the histogram data for group #${ + cpg.id + }, got: \n${e.toString()}` + ); + pushError(`Failed to fetch the histogram data for group #${cpg.id}.`); + } + return; + } + const histogram = + overallTimeSeries.data.map((o, i) => { + const current = cpgTimeSeries.data.find( + (d1) => d1.key_as_string === o.key_as_string + ) ?? { + doc_count: 0, + }; + return { + key: o.key, + key_as_string: o.key_as_string ?? '', + doc_count_significant_term: current.doc_count, + doc_count_overall: Math.max(0, o.doc_count - current.doc_count), + }; + }) ?? []; + + push( + addSignificantTermsGroupHistogramAction([ + { + id: cpg.id, + histogram, + }, + ]) + ); + } + }, MAX_CONCURRENT_QUERIES); + + groupHistogramQueue.push(significantTermGroups); + await groupHistogramQueue.drain(); + } + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to transform field/value pairs into groups, got: \n${e.toString()}` + ); + pushError(`Failed to transform field/value pairs into groups.`); + } } } - } - loaded += PROGRESS_STEP_HISTOGRAMS_GROUPS; + loaded += PROGRESS_STEP_HISTOGRAMS_GROUPS; - logDebugMessage(`Fetch ${significantTerms.length} field/value histograms.`); + logDebugMessage(`Fetch ${significantTerms.length} field/value histograms.`); - // time series filtered by fields - if ( - significantTerms.length > 0 && - overallTimeSeries !== undefined && - !request.body.overrides?.regroupOnly - ) { - const fieldValueHistogramQueue = queue(async function (cp: SignificantTerm) { - if (shouldStop) { - logDebugMessage('shouldStop abort fetching field/value histograms.'); - fieldValueHistogramQueue.kill(); - end(); - return; - } - - if (overallTimeSeries !== undefined) { - const histogramQuery = getHistogramQuery(request.body, [ - { - term: { [cp.fieldName]: cp.fieldValue }, - }, - ]); - - let cpTimeSeries: NumericChartData; - - try { - cpTimeSeries = ( - (await fetchHistogramsForFields( - client, - request.body.index, - histogramQuery, - // fields - [ - { - fieldName: request.body.timeFieldName, - type: KBN_FIELD_TYPES.DATE, - interval: overallTimeSeries.interval, - min: overallTimeSeries.stats[0], - max: overallTimeSeries.stats[1], - }, - ], - // samplerShardSize - -1, - undefined, - abortSignal, - sampleProbability, - RANDOM_SAMPLER_SEED - )) as [NumericChartData] - )[0]; - } catch (e) { - logger.error( - `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${ - cp.fieldValue - }", got: \n${e.toString()}` - ); - pushError( - `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${cp.fieldValue}".` - ); + // time series filtered by fields + if ( + significantTerms.length > 0 && + overallTimeSeries !== undefined && + !request.body.overrides?.regroupOnly + ) { + const fieldValueHistogramQueue = queue(async function (cp: SignificantTerm) { + if (shouldStop) { + logDebugMessage('shouldStop abort fetching field/value histograms.'); + fieldValueHistogramQueue.kill(); + end(); return; } - const histogram = - overallTimeSeries.data.map((o, i) => { - const current = cpTimeSeries.data.find( - (d1) => d1.key_as_string === o.key_as_string - ) ?? { - doc_count: 0, - }; - return { - key: o.key, - key_as_string: o.key_as_string ?? '', - doc_count_significant_term: current.doc_count, - doc_count_overall: Math.max(0, o.doc_count - current.doc_count), - }; - }) ?? []; - - const { fieldName, fieldValue } = cp; - - loaded += (1 / significantTerms.length) * PROGRESS_STEP_HISTOGRAMS; - pushHistogramDataLoadingState(); - push( - addSignificantTermsHistogramAction([ + if (overallTimeSeries !== undefined) { + const histogramQuery = getHistogramQuery(request.body, [ { - fieldName, - fieldValue, - histogram, + term: { [cp.fieldName]: cp.fieldValue }, }, - ]) - ); - } - }, MAX_CONCURRENT_QUERIES); + ]); + + let cpTimeSeries: NumericChartData; + + try { + cpTimeSeries = ( + (await fetchHistogramsForFields( + client, + request.body.index, + histogramQuery, + // fields + [ + { + fieldName: request.body.timeFieldName, + type: KBN_FIELD_TYPES.DATE, + interval: overallTimeSeries.interval, + min: overallTimeSeries.stats[0], + max: overallTimeSeries.stats[1], + }, + ], + // samplerShardSize + -1, + undefined, + abortSignal, + sampleProbability, + RANDOM_SAMPLER_SEED + )) as [NumericChartData] + )[0]; + } catch (e) { + logger.error( + `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${ + cp.fieldValue + }", got: \n${e.toString()}` + ); + pushError( + `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${cp.fieldValue}".` + ); + return; + } - fieldValueHistogramQueue.push(significantTerms); - await fieldValueHistogramQueue.drain(); - } + const histogram = + overallTimeSeries.data.map((o, i) => { + const current = cpTimeSeries.data.find( + (d1) => d1.key_as_string === o.key_as_string + ) ?? { + doc_count: 0, + }; + return { + key: o.key, + key_as_string: o.key_as_string ?? '', + doc_count_significant_term: current.doc_count, + doc_count_overall: Math.max(0, o.doc_count - current.doc_count), + }; + }) ?? []; + + const { fieldName, fieldValue } = cp; + + loaded += (1 / significantTerms.length) * PROGRESS_STEP_HISTOGRAMS; + pushHistogramDataLoadingState(); + push( + addSignificantTermsHistogramAction([ + { + fieldName, + fieldValue, + histogram, + }, + ]) + ); + } + }, MAX_CONCURRENT_QUERIES); - endWithUpdatedLoadingState(); - } catch (e) { - if (!isRequestAbortedError(e)) { - logger.error( - `Explain log rate spikes analysis failed to finish, got: \n${e.toString()}` - ); - pushError(`Explain log rate spikes analysis failed to finish.`); + fieldValueHistogramQueue.push(significantTerms); + await fieldValueHistogramQueue.drain(); + } + + endWithUpdatedLoadingState(); + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error( + `Explain log rate spikes analysis failed to finish, got: \n${e.toString()}` + ); + pushError(`Explain log rate spikes analysis failed to finish.`); + } + end(); } - end(); } - } - // Do not call this using `await` so it will run asynchronously while we return the stream already. - runAnalysis(); + // Do not call this using `await` so it will run asynchronously while we return the stream already. + runAnalysis(); - return response.ok(responseWithHeaders); - }); - } - ); + return response.ok(responseWithHeaders); + }); + } + ); }; diff --git a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_full_analysis.ts b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_full_analysis.ts index 5b48214d39bbd..2bbb5ea8e133d 100644 --- a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_full_analysis.ts +++ b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_full_analysis.ts @@ -10,8 +10,8 @@ import fetch from 'node-fetch'; import { format as formatUrl } from 'url'; import expect from '@kbn/expect'; - import type { ApiExplainLogRateSpikes } from '@kbn/aiops-plugin/common/api'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { FtrProviderContext } from '../../ftr_provider_context'; @@ -104,6 +104,7 @@ export default ({ getService }: FtrProviderContext) => { const resp = await supertest .post(`/internal/aiops/explain_log_rate_spikes`) .set('kbn-xsrf', 'kibana') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .send(body) .expect(200); @@ -161,6 +162,7 @@ export default ({ getService }: FtrProviderContext) => { method: 'POST', headers: { 'Content-Type': 'application/json', + [ELASTIC_HTTP_VERSION_HEADER]: '1', 'kbn-xsrf': 'stream', }, body: JSON.stringify(body), diff --git a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts index 451542c67885e..a515af80effd0 100644 --- a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts +++ b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts @@ -10,8 +10,8 @@ import fetch from 'node-fetch'; import { format as formatUrl } from 'url'; import expect from '@kbn/expect'; - import type { ApiExplainLogRateSpikes } from '@kbn/aiops-plugin/common/api'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { FtrProviderContext } from '../../ftr_provider_context'; @@ -96,6 +96,7 @@ export default ({ getService }: FtrProviderContext) => { const resp = await supertest .post(`/internal/aiops/explain_log_rate_spikes`) .set('kbn-xsrf', 'kibana') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .send(body) .expect(200); @@ -158,6 +159,7 @@ export default ({ getService }: FtrProviderContext) => { method: 'POST', headers: { 'Content-Type': 'application/json', + [ELASTIC_HTTP_VERSION_HEADER]: '1', 'kbn-xsrf': 'stream', }, body: JSON.stringify(body), diff --git a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_no_index.ts b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_no_index.ts index fb421697a98e1..c34e3ee5884aa 100644 --- a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_no_index.ts +++ b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_no_index.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'; @@ -21,6 +22,7 @@ export default ({ getService }: FtrProviderContext) => { const resp = await supertest .post(`/internal/aiops/explain_log_rate_spikes`) .set('kbn-xsrf', 'kibana') + .set(ELASTIC_HTTP_VERSION_HEADER, '1') .send({ ...testData.requestBody, index: 'does_not_exist', From 3ac1666c1d5f8a9c1e9c8272d5baed56142b639a Mon Sep 17 00:00:00 2001 From: David Kilfoyle <41695641+kilfoyle@users.noreply.github.com> Date: Thu, 1 Jun 2023 10:51:55 -0400 Subject: [PATCH 30/31] [Docs] Add new Fleet preconfiguration settings (#158771) This adds new Fleet preconfiguration settings to the Kibana [Fleet settings](https://www.elastic.co/guide/en/kibana/master/fleet-settings-kb.html) page. I also moved the "example configuration" to right below the `xpack.fleet.agentPolicies` setting, since that's what's shown in the example. [Preview page](https://kibana_158771.docs-preview.app.elstc.co/guide/en/kibana/master/fleet-settings-kb.html) Closes: https://github.com/elastic/ingest-docs/issues/191 --- docs/settings/fleet-settings.asciidoc | 132 +++++++++++++++++++------- 1 file changed, 97 insertions(+), 35 deletions(-) diff --git a/docs/settings/fleet-settings.asciidoc b/docs/settings/fleet-settings.asciidoc index 28a855c29bace..0960937564b7d 100644 --- a/docs/settings/fleet-settings.asciidoc +++ b/docs/settings/fleet-settings.asciidoc @@ -52,12 +52,11 @@ Hostnames used by {agent} for accessing {es}. `xpack.fleet.agents.elasticsearch.ca_sha256`:: Hash pin used for certificate verification. The pin is a base64-encoded string of the SHA-256 fingerprint. - [role="child_attributes"] ==== Preconfiguration settings (for advanced use cases) -Use these settings to pre-define integrations and agent policies that you -want {fleet} to load up by default. +Use these settings to pre-define integrations, agent policies, and {fleet-server} +hosts or proxies that you want {fleet} to load up by default. NOTE: These settings are not supported to pre-configure the Endpoint and Cloud Security integration. @@ -134,6 +133,41 @@ List of agent policies that are configured when the {fleet} app starts. Array that overrides any default input settings for this integration. Follows the same schema as integration inputs, with the exception that any object in `vars` can be passed `frozen: true` in order to prevent that specific `var` from being edited by the user. ======= ===== ++ +Example configuration: ++ +[source,yaml] +---- +xpack.fleet.packages: + - name: apache + version: 0.5.0 + +xpack.fleet.agentPolicies: + - name: Preconfigured Policy + id: 1 + namespace: test + package_policies: + - package: + name: system + name: System Integration + id: preconfigured-system + inputs: + - type: system/metrics + enabled: true + vars: + - name: system.hostfs + value: home/test + streams: + - data_stream: + dataset: system.core + enabled: true + vars: + - name: period + value: 20s + - type: winlog + enabled: false +---- + `xpack.fleet.outputs`:: List of outputs that are configured when the {fleet} app starts. @@ -157,6 +191,8 @@ NOTE: The `xpack.fleet.outputs` settings are intended for advanced configuration Array that contains the list of host for that output. `config`::: Extra config for that output. + `proxy_id`::: + Unique ID of a proxy to access the output. ===== + .Optional properties of `xpack.fleet.outputs` @@ -167,40 +203,66 @@ NOTE: The `xpack.fleet.outputs` settings are intended for advanced configuration `is_default_monitoring`::: If `true`, the output specified in `xpack.fleet.outputs` will be the one used to send agent monitoring data unless there is another one configured specifically for the agent policy. ===== + +`xpack.fleet.fleetServerHosts`:: +List of {fleet-server} hosts that are configured when the {fleet} app starts. + -Example configuration: +.Required properties of `xpack.fleet.fleetServerHosts` +[%collapsible%open] +===== + `id`::: + Unique ID for the host server. + `name`::: + Name of the host server. + `host_urls`::: + Array of one or more host URLs that {agents} will use to connect to {fleet-server}. +===== + -[source,yaml] ----- -xpack.fleet.packages: - - name: apache - version: 0.5.0 +.Optional properties of `xpack.fleet.fleetServerHosts` +[%collapsible%open] +===== + `is_default`::: + Whether or not this host should be the default to use for {fleet-server}. + `proxy_id`::: + Unique ID of the proxy to access the {fleet-server} host. +===== -xpack.fleet.agentPolicies: - - name: Preconfigured Policy - id: 1 - namespace: test - package_policies: - - package: - name: system - name: System Integration - id: preconfigured-system - inputs: - - type: system/metrics - enabled: true - vars: - - name: system.hostfs - value: home/test - streams: - - data_stream: - dataset: system.core - enabled: true - vars: - - name: period - value: 20s - - type: winlog - enabled: false ----- +`xpack.fleet.proxy`:: +List of proxies to access {fleet-server} that are configured when the {fleet} app starts. ++ +.Required properties of `xpack.fleet.proxy` +[%collapsible%open] +===== + `id`::: + Unique ID of the proxy to access the {fleet-server} host. + `name`::: + Name of the proxy to access the {fleet-server} host. + `url`::: + URL that {agents} use to connect to the proxy to access {fleet-server}. +===== ++ +.Optional properties of `xpack.fleet.proxy` +[%collapsible%open] +===== + `proxy_headers`::: + Map of headers to use with the proxy. +.Properties of `proxy_headers` +[%collapsible%open] +======= + `key`:::: + Key to use for the proxy header. + `value`:::: + Value to use for the proxy header. +======= + `certificate_authorities`::: + Certificate authority (CA) used to issue the certificate. + `certificate`::: + The name of the certificate used to authenticate the proxy. + `certificate_key`::: + The certificate key used to authenticate the proxy. +===== `xpack.fleet.enableExperimental`:: -List of experimental feature flag to enable in Fleet. \ No newline at end of file +List of experimental feature flag to enable in Fleet. + + From cdecdc873217ca5b45de877c0eda0b1cacb062ca Mon Sep 17 00:00:00 2001 From: Tim Grein Date: Thu, 1 Jun 2023 17:15:10 +0200 Subject: [PATCH 31/31] [Enterprise Search] Add "last_access_control_sync_scheduled_at" field to connector (#158823) --- x-pack/plugins/enterprise_search/common/types/connectors.ts | 1 + .../enterprise_search_content/__mocks__/search_indices.mock.ts | 2 ++ .../enterprise_search_content/__mocks__/view_index.mock.ts | 2 ++ .../server/index_management/setup_indices.test.ts | 1 + .../enterprise_search/server/index_management/setup_indices.ts | 1 + .../server/lib/connectors/add_connector.test.ts | 3 +++ .../enterprise_search/server/lib/connectors/start_sync.test.ts | 1 + .../server/lib/connectors/update_connector_scheduling.test.ts | 2 ++ .../server/lib/crawler/post_connector.test.ts | 1 + .../server/utils/create_connector_document.test.ts | 2 ++ .../server/utils/create_connector_document.ts | 1 + 11 files changed, 17 insertions(+) diff --git a/x-pack/plugins/enterprise_search/common/types/connectors.ts b/x-pack/plugins/enterprise_search/common/types/connectors.ts index 0506213ea3ecd..bd3314bae8de5 100644 --- a/x-pack/plugins/enterprise_search/common/types/connectors.ts +++ b/x-pack/plugins/enterprise_search/common/types/connectors.ts @@ -191,6 +191,7 @@ export interface Connector { index_name: string; is_native: boolean; language: string | null; + last_access_control_sync_scheduled_at: string | null; last_access_control_sync_status: SyncStatus | null; last_seen: string | null; last_sync_error: string | null; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts index 4359937bde25c..662021dc9f6ed 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/search_indices.mock.ts @@ -118,6 +118,7 @@ export const indices: ElasticsearchIndexWithIngestion[] = [ index_name: 'connector', is_native: false, language: 'en', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: SyncStatus.COMPLETED, last_seen: null, last_sync_error: null, @@ -231,6 +232,7 @@ export const indices: ElasticsearchIndexWithIngestion[] = [ index_name: 'crawler', is_native: true, language: 'en', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: SyncStatus.COMPLETED, last_seen: null, last_sync_error: null, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts index fa9392939bab0..c06e88e237ba5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/__mocks__/view_index.mock.ts @@ -128,6 +128,7 @@ export const connectorIndex: ConnectorViewIndex = { index_name: 'connector', is_native: false, language: 'en', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: SyncStatus.COMPLETED, last_seen: null, last_sync_error: null, @@ -245,6 +246,7 @@ export const crawlerIndex: CrawlerViewIndex = { index_name: 'crawler', is_native: true, language: 'en', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: SyncStatus.COMPLETED, last_seen: null, last_sync_error: null, diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts index 299fa7d1d1484..731b9cadf6428 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts @@ -145,6 +145,7 @@ describe('Setup Indices', () => { index_name: { type: 'keyword' }, is_native: { type: 'boolean' }, language: { type: 'keyword' }, + last_access_control_sync_scheduled_at: { type: 'date' }, last_access_control_sync_status: { type: 'keyword' }, last_deleted_document_count: { type: 'long' }, last_incremental_sync_scheduled_at: { type: 'date' }, diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts index 3de57c8fc2a65..5629cbbe073dd 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts @@ -134,6 +134,7 @@ const connectorMappingsProperties: Record = { index_name: { type: 'keyword' }, is_native: { type: 'boolean' }, language: { type: 'keyword' }, + last_access_control_sync_scheduled_at: { type: 'date' }, last_access_control_sync_status: { type: 'keyword' }, last_deleted_document_count: { type: 'long' }, last_incremental_sync_scheduled_at: { type: 'date' }, diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts index 922470bbf218f..8eb4454397ab2 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts @@ -144,6 +144,7 @@ describe('addConnector lib function', () => { index_name: 'index_name', is_native: false, language: 'fr', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, @@ -328,6 +329,7 @@ describe('addConnector lib function', () => { index_name: 'index_name', is_native: true, language: null, + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, @@ -437,6 +439,7 @@ describe('addConnector lib function', () => { index_name: 'search-index_name', is_native: false, language: 'en', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, 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 b07ed78a2a402..54e0c3f91eb30 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 @@ -40,6 +40,7 @@ describe('startSync lib function', () => { error: null, index_name: 'index_name', language: null, + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_scheduling.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_scheduling.test.ts index ad3c8a60f1628..7ca6f779fb569 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_scheduling.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_scheduling.test.ts @@ -37,6 +37,7 @@ describe('addConnector lib function', () => { custom_scheduling: {}, error: null, index_name: 'index_name', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, @@ -67,6 +68,7 @@ describe('addConnector lib function', () => { custom_scheduling: {}, error: null, index_name: 'index_name', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, diff --git a/x-pack/plugins/enterprise_search/server/lib/crawler/post_connector.test.ts b/x-pack/plugins/enterprise_search/server/lib/crawler/post_connector.test.ts index 150a0858c1f20..c758c982222d0 100644 --- a/x-pack/plugins/enterprise_search/server/lib/crawler/post_connector.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/crawler/post_connector.test.ts @@ -90,6 +90,7 @@ describe('recreateConnectorDocument lib function', () => { index_name: 'indexName', is_native: false, language: '', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, diff --git a/x-pack/plugins/enterprise_search/server/utils/create_connector_document.test.ts b/x-pack/plugins/enterprise_search/server/utils/create_connector_document.test.ts index 01d3a6b981591..97bc581263b9f 100644 --- a/x-pack/plugins/enterprise_search/server/utils/create_connector_document.test.ts +++ b/x-pack/plugins/enterprise_search/server/utils/create_connector_document.test.ts @@ -85,6 +85,7 @@ describe('createConnectorDocument', () => { index_name: 'indexName', is_native: false, language: 'fr', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, @@ -179,6 +180,7 @@ describe('createConnectorDocument', () => { index_name: 'search-indexName', is_native: false, language: 'fr', + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null, diff --git a/x-pack/plugins/enterprise_search/server/utils/create_connector_document.ts b/x-pack/plugins/enterprise_search/server/utils/create_connector_document.ts index 0b3f737bb96b9..d91b18056fa15 100644 --- a/x-pack/plugins/enterprise_search/server/utils/create_connector_document.ts +++ b/x-pack/plugins/enterprise_search/server/utils/create_connector_document.ts @@ -114,6 +114,7 @@ export function createConnectorDocument({ index_name: indexName, is_native: isNative, language, + last_access_control_sync_scheduled_at: null, last_access_control_sync_status: null, last_seen: null, last_sync_error: null,