From 2722123220d209da6963dae373c60d3572c746cc Mon Sep 17 00:00:00 2001 From: "Quynh Nguyen (Quinn)" <43350163+qn895@users.noreply.github.com> Date: Tue, 20 Sep 2022 14:01:03 -0500 Subject: [PATCH 01/55] [ML] Update installation mechanism for Transforms in Fleet according to new specifications (#140046) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../epm/elasticsearch/template/install.ts | 2 +- .../epm/elasticsearch/transform/install.ts | 402 ++++++++++++++++-- .../elasticsearch/transform/transform.test.ts | 10 +- .../services/epm/package_service.test.ts | 2 +- .../server/services/epm/package_service.ts | 4 +- .../services/epm/packages/_install_package.ts | 4 +- 6 files changed, 371 insertions(+), 53 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts index dab8f3c0bf82e..527b93a66d130 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts @@ -223,7 +223,7 @@ type UserSettingsTemplateName = `${TemplateBaseName}${typeof USER_SETTINGS_TEMPL const isUserSettingsTemplate = (name: string): name is UserSettingsTemplateName => name.endsWith(USER_SETTINGS_TEMPLATE_SUFFIX); -function buildComponentTemplates(params: { +export function buildComponentTemplates(params: { mappings: IndexTemplateMappings; templateName: string; registryElasticsearch: RegistryElasticsearch | undefined; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts index ab8f60e172dcb..8c908ecc9ef87 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/install.ts @@ -7,65 +7,71 @@ import type { ElasticsearchClient, Logger, SavedObjectsClientContract } from '@kbn/core/server'; import { errors } from '@elastic/elasticsearch'; +import { safeLoad } from 'js-yaml'; +import { isPopulatedObject } from '@kbn/ml-is-populated-object'; +import { + PACKAGE_TEMPLATE_SUFFIX, + USER_SETTINGS_TEMPLATE_SUFFIX, +} from '../../../../../common/constants'; +import { + buildComponentTemplates, + installComponentAndIndexTemplateForDataStream, +} from '../template/install'; +import { processFields } from '../../fields/field'; +import { generateMappings } from '../template/template'; +import { getESAssetMetadata } from '../meta'; import { updateEsAssetReferences } from '../../packages/install'; import { getPathParts } from '../../archive'; import { ElasticsearchAssetType } from '../../../../../common/types/models'; -import type { EsAssetReference, InstallablePackage } from '../../../../../common/types/models'; +import type { + EsAssetReference, + InstallablePackage, + ESAssetMetadata, + IndexTemplate, + RegistryElasticsearch, +} from '../../../../../common/types/models'; import { getInstallation } from '../../packages'; - -import { getESAssetMetadata } from '../meta'; - import { retryTransientEsErrors } from '../retry'; import { deleteTransforms } from './remove'; import { getAsset } from './common'; -interface TransformInstallation { +const DEFAULT_TRANSFORM_TEMPLATES_PRIORITY = 250; +enum TRANSFORM_SPECS_TYPES { + MANIFEST = 'manifest', + FIELDS = 'fields', + TRANSFORM = 'transform', +} + +interface TransformModuleBase { + transformModuleId?: string; +} +interface DestinationIndexTemplateInstallation extends TransformModuleBase { + installationName: string; + _meta: ESAssetMetadata; + template: IndexTemplate['template']; +} +interface TransformInstallation extends TransformModuleBase { installationName: string; content: any; } -export const installTransform = async ( +const installLegacyTransformsAssets = async ( installablePackage: InstallablePackage, - paths: string[], + installNameSuffix: string, + transformPaths: string[], esClient: ElasticsearchClient, savedObjectsClient: SavedObjectsClientContract, logger: Logger, - esReferences?: EsAssetReference[] + esReferences: EsAssetReference[] = [], + previousInstalledTransformEsAssets: EsAssetReference[] = [] ) => { - const installation = await getInstallation({ - savedObjectsClient, - pkgName: installablePackage.name, - }); - esReferences = esReferences ?? installation?.installed_es ?? []; - let previousInstalledTransformEsAssets: EsAssetReference[] = []; - if (installation) { - previousInstalledTransformEsAssets = installation.installed_es.filter( - ({ type, id }) => type === ElasticsearchAssetType.transform - ); - if (previousInstalledTransformEsAssets.length) { - logger.info( - `Found previous transform references:\n ${JSON.stringify( - previousInstalledTransformEsAssets - )}` - ); - } - } - - // delete all previous transform - await deleteTransforms( - esClient, - previousInstalledTransformEsAssets.map((asset) => asset.id) - ); - - const installNameSuffix = `${installablePackage.version}`; - const transformPaths = paths.filter((path) => isTransform(path)); let installedTransforms: EsAssetReference[] = []; if (transformPaths.length > 0) { const transformRefs = transformPaths.reduce((acc, path) => { acc.push({ - id: getTransformNameForInstallation(installablePackage, path, installNameSuffix), + id: getLegacyTransformNameForInstallation(installablePackage, path, installNameSuffix), type: ElasticsearchAssetType.transform, }); @@ -87,7 +93,7 @@ export const installTransform = async ( content._meta = getESAssetMetadata({ packageName: installablePackage.name }); return { - installationName: getTransformNameForInstallation( + installationName: getLegacyTransformNameForInstallation( installablePackage, path, installNameSuffix @@ -117,6 +123,289 @@ export const installTransform = async ( return { installedTransforms, esReferences }; }; +const processTransformAssetsPerModule = ( + installablePackage: InstallablePackage, + installNameSuffix: string, + transformPaths: string[] +) => { + const transformsSpecifications = new Map(); + const destinationIndexTemplates: DestinationIndexTemplateInstallation[] = []; + const transforms: TransformInstallation[] = []; + + transformPaths.forEach((path: string) => { + const { transformModuleId, fileName } = getTransformFolderAndFileNames( + installablePackage, + path + ); + + // Since there can be multiple assets per transform definition + // We want to create a unique list of assets/specifications for each transform + if (transformsSpecifications.get(transformModuleId) === undefined) { + transformsSpecifications.set(transformModuleId, new Map()); + } + const packageAssets = transformsSpecifications.get(transformModuleId); + + const content = safeLoad(getAsset(path).toString('utf-8')); + + if (fileName === TRANSFORM_SPECS_TYPES.FIELDS) { + const validFields = processFields(content); + const mappings = generateMappings(validFields); + packageAssets?.set('mappings', mappings); + } + + if (fileName === TRANSFORM_SPECS_TYPES.TRANSFORM) { + transformsSpecifications.get(transformModuleId)?.set('destinationIndex', content.dest); + transformsSpecifications.get(transformModuleId)?.set('transform', content); + content._meta = getESAssetMetadata({ packageName: installablePackage.name }); + transforms.push({ + transformModuleId, + installationName: getTransformAssetNameForInstallation( + installablePackage, + transformModuleId, + `default-${installNameSuffix}` + ), + content, + }); + } + + if (fileName === TRANSFORM_SPECS_TYPES.MANIFEST) { + if (isPopulatedObject(content, ['start']) && content.start === false) { + transformsSpecifications.get(transformModuleId)?.set('start', false); + } + // If manifest.yml contains destination_index_template + // Combine the mappings and other index template settings from manifest.yml into a single index template + // Create the index template and track the template in EsAssetReferences + if ( + isPopulatedObject(content, ['destination_index_template']) || + isPopulatedObject(packageAssets.get('mappings')) + ) { + const destinationIndexTemplate = + (content.destination_index_template as Record) ?? {}; + destinationIndexTemplates.push({ + transformModuleId, + _meta: getESAssetMetadata({ packageName: installablePackage.name }), + installationName: getTransformAssetNameForInstallation( + installablePackage, + transformModuleId, + 'template' + ), + template: destinationIndexTemplate, + } as DestinationIndexTemplateInstallation); + packageAssets.set('destinationIndexTemplate', destinationIndexTemplate); + } + } + }); + + const indexTemplatesRefs = destinationIndexTemplates.map((template) => ({ + id: template.installationName, + type: ElasticsearchAssetType.indexTemplate, + })); + const componentTemplatesRefs = [ + ...destinationIndexTemplates.map((template) => ({ + id: `${template.installationName}${USER_SETTINGS_TEMPLATE_SUFFIX}`, + type: ElasticsearchAssetType.componentTemplate, + })), + ...destinationIndexTemplates.map((template) => ({ + id: `${template.installationName}${PACKAGE_TEMPLATE_SUFFIX}`, + type: ElasticsearchAssetType.componentTemplate, + })), + ]; + + const transformRefs = transforms.map((t) => ({ + id: t.installationName, + type: ElasticsearchAssetType.transform, + })); + + return { + indexTemplatesRefs, + componentTemplatesRefs, + transformRefs, + transforms, + destinationIndexTemplates, + transformsSpecifications, + }; +}; + +const installTransformsAssets = async ( + installablePackage: InstallablePackage, + installNameSuffix: string, + transformPaths: string[], + esClient: ElasticsearchClient, + savedObjectsClient: SavedObjectsClientContract, + logger: Logger, + esReferences: EsAssetReference[] = [], + previousInstalledTransformEsAssets: EsAssetReference[] = [] +) => { + let installedTransforms: EsAssetReference[] = []; + if (transformPaths.length > 0) { + const { + indexTemplatesRefs, + componentTemplatesRefs, + transformRefs, + transforms, + destinationIndexTemplates, + transformsSpecifications, + } = processTransformAssetsPerModule(installablePackage, installNameSuffix, transformPaths); + // get and save refs associated with the transforms before installing + esReferences = await updateEsAssetReferences( + savedObjectsClient, + installablePackage.name, + esReferences, + { + assetsToAdd: [...indexTemplatesRefs, ...componentTemplatesRefs, ...transformRefs], + assetsToRemove: previousInstalledTransformEsAssets, + } + ); + + // create index templates and component templates + await Promise.all( + destinationIndexTemplates + .map((destinationIndexTemplate) => { + const customMappings = transformsSpecifications + .get(destinationIndexTemplate.transformModuleId) + ?.get('mappings'); + const registryElasticsearch: RegistryElasticsearch = { + 'index_template.settings': destinationIndexTemplate.template.settings, + 'index_template.mappings': destinationIndexTemplate.template.mappings, + }; + + const componentTemplates = buildComponentTemplates({ + mappings: customMappings, + templateName: destinationIndexTemplate.installationName, + registryElasticsearch, + packageName: installablePackage.name, + defaultSettings: {}, + }); + + if (destinationIndexTemplate || customMappings) { + return installComponentAndIndexTemplateForDataStream({ + esClient, + logger, + componentTemplates, + indexTemplate: { + templateName: destinationIndexTemplate.installationName, + // @ts-expect-error We don't need to pass data_stream property here + // as this template is applied to only an index and not a data stream + indexTemplate: { + template: { settings: undefined, mappings: undefined }, + priority: DEFAULT_TRANSFORM_TEMPLATES_PRIORITY, + index_patterns: [ + transformsSpecifications + .get(destinationIndexTemplate.transformModuleId) + ?.get('destinationIndex').index, + ], + _meta: destinationIndexTemplate._meta, + composed_of: Object.keys(componentTemplates), + }, + }, + }); + } + }) + .filter((p) => p !== undefined) + ); + + // create destination indices + await Promise.all( + transforms.map(async (transform) => { + const index = transform.content.dest.index; + const pipelineId = transform.content.dest.pipeline; + + try { + await retryTransientEsErrors( + () => + esClient.indices.create( + { + index, + ...(pipelineId ? { settings: { default_pipeline: pipelineId } } : {}), + }, + { ignore: [400] } + ), + { logger } + ); + } catch (err) { + throw new Error(err.message); + } + }) + ); + + // create & optionally start transforms + const transformsPromises = transforms.map(async (transform) => { + return handleTransformInstall({ + esClient, + logger, + transform, + startTransform: transformsSpecifications.get(transform.transformModuleId)?.get('start'), + }); + }); + + installedTransforms = await Promise.all(transformsPromises).then((results) => results.flat()); + } + + return { installedTransforms, esReferences }; +}; +export const installTransforms = async ( + installablePackage: InstallablePackage, + paths: string[], + esClient: ElasticsearchClient, + savedObjectsClient: SavedObjectsClientContract, + logger: Logger, + esReferences?: EsAssetReference[] +) => { + const transformPaths = paths.filter((path) => isTransform(path)); + + const installation = await getInstallation({ + savedObjectsClient, + pkgName: installablePackage.name, + }); + esReferences = esReferences ?? installation?.installed_es ?? []; + let previousInstalledTransformEsAssets: EsAssetReference[] = []; + if (installation) { + previousInstalledTransformEsAssets = installation.installed_es.filter( + ({ type, id }) => type === ElasticsearchAssetType.transform + ); + if (previousInstalledTransformEsAssets.length) { + logger.debug( + `Found previous transform references:\n ${JSON.stringify( + previousInstalledTransformEsAssets + )}` + ); + } + } + + // delete all previous transform + await deleteTransforms( + esClient, + previousInstalledTransformEsAssets.map((asset) => asset.id) + ); + + const installNameSuffix = `${installablePackage.version}`; + + // If package contains legacy transform specifications (i.e. with json instead of yml) + if (transformPaths.some((p) => p.endsWith('.json')) || transformPaths.length === 0) { + return await installLegacyTransformsAssets( + installablePackage, + installNameSuffix, + transformPaths, + esClient, + savedObjectsClient, + logger, + esReferences, + previousInstalledTransformEsAssets + ); + } + + return await installTransformsAssets( + installablePackage, + installNameSuffix, + transformPaths, + esClient, + savedObjectsClient, + logger, + esReferences, + previousInstalledTransformEsAssets + ); +}; + export const isTransform = (path: string) => { const pathParts = getPathParts(path); return !path.endsWith('/') && pathParts.type === ElasticsearchAssetType.transform; @@ -126,10 +415,12 @@ async function handleTransformInstall({ esClient, logger, transform, + startTransform, }: { esClient: ElasticsearchClient; logger: Logger; transform: TransformInstallation; + startTransform?: boolean; }): Promise { try { await retryTransientEsErrors( @@ -151,15 +442,21 @@ async function handleTransformInstall({ throw err; } } - await esClient.transform.startTransform( - { transform_id: transform.installationName }, - { ignore: [409] } - ); + + // start transform by default if not set in yml file + // else, respect the setting + if (startTransform === undefined || startTransform === true) { + await esClient.transform.startTransform( + { transform_id: transform.installationName }, + { ignore: [409] } + ); + logger.debug(`Started transform: ${transform.installationName}`); + } return { id: transform.installationName, type: ElasticsearchAssetType.transform }; } -const getTransformNameForInstallation = ( +const getLegacyTransformNameForInstallation = ( installablePackage: InstallablePackage, path: string, suffix: string @@ -169,3 +466,24 @@ const getTransformNameForInstallation = ( const folderName = pathPaths?.pop(); return `${installablePackage.name}.${folderName}-${filename}-${suffix}`; }; + +const getTransformAssetNameForInstallation = ( + installablePackage: InstallablePackage, + transformModuleId: string, + suffix?: string +) => { + return `logs-${installablePackage.name}.${transformModuleId}${suffix ? '-' + suffix : ''}`; +}; + +const getTransformFolderAndFileNames = (installablePackage: InstallablePackage, path: string) => { + const pathPaths = path.split('/'); + const fileName = pathPaths?.pop()?.split('.')[0]; + let transformModuleId = pathPaths?.pop(); + + // If fields.yml is located inside a directory called 'fields' (e.g. {exampleFolder}/fields/fields.yml) + // We need to go one level up to get the real folder name + if (transformModuleId === 'fields') { + transformModuleId = pathPaths?.pop(); + } + return { fileName: fileName ?? '', transformModuleId: transformModuleId ?? '' }; +}; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts index 1b8c347ad07d5..97fa1e94ca218 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts @@ -35,7 +35,7 @@ import { getESAssetMetadata } from '../meta'; import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../../constants'; import { getAsset } from './common'; -import { installTransform } from './install'; +import { installTransforms } from './install'; describe('test transform install', () => { let esClient: ReturnType; @@ -122,7 +122,7 @@ describe('test transform install', () => { ], }); - await installTransform( + await installTransforms( { name: 'endpoint', version: '0.16.0-dev.0', @@ -320,7 +320,7 @@ describe('test transform install', () => { } as unknown as SavedObject) ); - await installTransform( + await installTransforms( { name: 'endpoint', version: '0.16.0-dev.0', @@ -422,7 +422,7 @@ describe('test transform install', () => { ], }); - await installTransform( + await installTransforms( { name: 'endpoint', version: '0.16.0-dev.0', @@ -556,7 +556,7 @@ describe('test transform install', () => { ) ); - await installTransform( + await installTransforms( { name: 'endpoint', version: '0.16.0-dev.0', diff --git a/x-pack/plugins/fleet/server/services/epm/package_service.test.ts b/x-pack/plugins/fleet/server/services/epm/package_service.test.ts index 1dc4039a7c2a7..4f98776f53d60 100644 --- a/x-pack/plugins/fleet/server/services/epm/package_service.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/package_service.test.ts @@ -128,7 +128,7 @@ function getTest( test = { method: mocks.packageClient.reinstallEsAssets.bind(mocks.packageClient), args: [pkg, paths], - spy: jest.spyOn(epmTransformsInstall, 'installTransform'), + spy: jest.spyOn(epmTransformsInstall, 'installTransforms'), spyArgs: [pkg, paths, mocks.esClient, mocks.soClient, mocks.logger], spyResponse: { installedTransforms: [ diff --git a/x-pack/plugins/fleet/server/services/epm/package_service.ts b/x-pack/plugins/fleet/server/services/epm/package_service.ts index c43386acdbdf4..71ab87c7d92bd 100644 --- a/x-pack/plugins/fleet/server/services/epm/package_service.ts +++ b/x-pack/plugins/fleet/server/services/epm/package_service.ts @@ -24,7 +24,7 @@ import type { import { checkSuperuser } from '../../routes/security'; import { FleetUnauthorizedError } from '../../errors'; -import { installTransform, isTransform } from './elasticsearch/transform/install'; +import { installTransforms, isTransform } from './elasticsearch/transform/install'; import { fetchFindLatestPackageOrThrow, getRegistryPackage } from './registry'; import { ensureInstalledPackage, getInstallation } from './packages'; @@ -151,7 +151,7 @@ class PackageClientImpl implements PackageClient { } async #reinstallTransforms(packageInfo: InstallablePackage, paths: string[]) { - const { installedTransforms } = await installTransform( + const { installedTransforms } = await installTransforms( packageInfo, paths, this.internalEsClient, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts index 8168bb05e53a4..4ecec17560731 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts @@ -42,7 +42,7 @@ import { import { installILMPolicy } from '../elasticsearch/ilm/install'; import { installKibanaAssetsAndReferences } from '../kibana/assets/install'; import { updateCurrentWriteIndices } from '../elasticsearch/template/template'; -import { installTransform } from '../elasticsearch/transform/install'; +import { installTransforms } from '../elasticsearch/transform/install'; import { installMlModel } from '../elasticsearch/ml_model'; import { installIlmForDataStream } from '../elasticsearch/datastream_ilm/install'; import { saveArchiveEntries } from '../archive/storage'; @@ -219,7 +219,7 @@ export async function _installPackage({ ); ({ esReferences } = await withPackageSpan('Install transforms', () => - installTransform(packageInfo, paths, esClient, savedObjectsClient, logger, esReferences) + installTransforms(packageInfo, paths, esClient, savedObjectsClient, logger, esReferences) )); // If this is an update or retrying an update, delete the previous version's pipelines From 333548e8a52c9ce500c3656f89b49c715c4b0287 Mon Sep 17 00:00:00 2001 From: Nick Peihl Date: Tue, 20 Sep 2022 15:02:03 -0400 Subject: [PATCH 02/55] [Maps] Track map embeddable usage with ui counters (#140994) * Track map embeddable usage with ui counters * Change subscription to pipe(first()) The rxjs .toPromise() method is deprecated and the lastValueFrom function is the suggested replacement. * review feedback --- .../maps/public/embeddable/map_embeddable_factory.ts | 11 +++++++++++ x-pack/plugins/maps/public/kibana_services.ts | 1 + 2 files changed, 12 insertions(+) diff --git a/x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts b/x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts index 6f823f218ca23..3642448774c58 100644 --- a/x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts +++ b/x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { first } from 'rxjs/operators'; import { i18n } from '@kbn/i18n'; import { EmbeddableFactoryDefinition, IContainer } from '@kbn/embeddable-plugin/public'; import { MAP_SAVED_OBJECT_TYPE, APP_ICON } from '../../common/constants'; @@ -12,6 +13,7 @@ import { getMapEmbeddableDisplayName } from '../../common/i18n_getters'; import { extract, inject } from '../../common/embeddable'; import { MapByReferenceInput, MapEmbeddableInput } from './types'; import { lazyLoadMapModules } from '../lazy_load_bundle'; +import { getApplication, getUsageCollection } from '../kibana_services'; export class MapEmbeddableFactory implements EmbeddableFactoryDefinition { type = MAP_SAVED_OBJECT_TYPE; @@ -50,6 +52,15 @@ export class MapEmbeddableFactory implements EmbeddableFactoryDefinition { create = async (input: MapEmbeddableInput, parent?: IContainer) => { const { MapEmbeddable } = await lazyLoadMapModules(); + const usageCollection = getUsageCollection(); + if (usageCollection) { + // currentAppId$ is a BehaviorSubject exposed as an observable so subscription gets last value upon subscribe + getApplication() + .currentAppId$.pipe(first()) + .subscribe((appId) => { + if (appId) usageCollection.reportUiCounter('map', 'loaded', `open_maps_vis_${appId}`); + }); + } return new MapEmbeddable( { editable: await this.isEditable(), diff --git a/x-pack/plugins/maps/public/kibana_services.ts b/x-pack/plugins/maps/public/kibana_services.ts index 41f88de18720c..a1a8a19674a81 100644 --- a/x-pack/plugins/maps/public/kibana_services.ts +++ b/x-pack/plugins/maps/public/kibana_services.ts @@ -66,6 +66,7 @@ export const getPresentationUtilContext = () => pluginsStart.presentationUtil.Co export const getSecurityService = () => pluginsStart.security; export const getSpacesApi = () => pluginsStart.spaces; export const getTheme = () => coreStart.theme; +export const getApplication = () => coreStart.application; export const getUsageCollection = () => pluginsStart.usageCollection; export const isScreenshotMode = () => { return pluginsStart.screenshotMode ? pluginsStart.screenshotMode.isScreenshotMode() : false; From 7d21c5f10b58210e0cb63dad5b59d44045b74e3e Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 20 Sep 2022 14:01:33 -0500 Subject: [PATCH 03/55] skip flaky suite. #140907 --- .../host_isolation_exceptions/view/components/form.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx index 23f8ea83a7094..4c7ac15a504a7 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx @@ -29,7 +29,8 @@ import type { HttpFetchOptionsWithPath } from '@kbn/core/public'; jest.mock('../../../../../common/components/user_privileges'); -describe('When on the host isolation exceptions entry form', () => { +// FLAKY: https://github.com/elastic/kibana/issues/140907 +describe.skip('When on the host isolation exceptions entry form', () => { let render: () => Promise>; let renderResult: ReturnType; let history: AppContextTestRender['history']; From 1598523b4f537c3ee31701dbc073174e3ab2135f Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 20 Sep 2022 21:23:12 +0200 Subject: [PATCH 04/55] [ML] Explain Log Rate Spikes: Add mini histograms to grouped results table. (#141065) - Adds mini histograms to grouped results table. - Fixes row expansion issue where expanded row could show up under wrong row. --- x-pack/packages/ml/agg_utils/index.ts | 1 + x-pack/packages/ml/agg_utils/src/types.ts | 10 ++ .../api/explain_log_rate_spikes/actions.ts | 23 +++- .../api/explain_log_rate_spikes/index.ts | 1 + .../aiops/common/api/stream_reducer.ts | 9 ++ .../explain_log_rate_spikes_analysis.tsx | 5 +- .../spike_analysis_table_groups.tsx | 50 +++++++- .../server/routes/explain_log_rate_spikes.ts | 116 ++++++++++++++---- .../get_simple_hierarchical_tree.test.ts | 4 + .../queries/get_simple_hierarchical_tree.ts | 9 +- 10 files changed, 196 insertions(+), 32 deletions(-) diff --git a/x-pack/packages/ml/agg_utils/index.ts b/x-pack/packages/ml/agg_utils/index.ts index ac51405d0b8eb..cc7a426f94050 100644 --- a/x-pack/packages/ml/agg_utils/index.ts +++ b/x-pack/packages/ml/agg_utils/index.ts @@ -16,6 +16,7 @@ export type { AggCardinality, ChangePoint, ChangePointGroup, + ChangePointGroupHistogram, ChangePointHistogram, ChangePointHistogramItem, HistogramField, diff --git a/x-pack/packages/ml/agg_utils/src/types.ts b/x-pack/packages/ml/agg_utils/src/types.ts index de993e4b9f321..a2c0d9f9a1569 100644 --- a/x-pack/packages/ml/agg_utils/src/types.ts +++ b/x-pack/packages/ml/agg_utils/src/types.ts @@ -87,6 +87,14 @@ export interface ChangePointHistogram extends FieldValuePair { histogram: ChangePointHistogramItem[]; } +/** + * Change point histogram data for a group of field/value pairs. + */ +export interface ChangePointGroupHistogram { + id: string; + histogram: ChangePointHistogramItem[]; +} + interface ChangePointGroupItem extends FieldValuePair { duplicate?: boolean; } @@ -95,7 +103,9 @@ interface ChangePointGroupItem extends FieldValuePair { * Tree leaves */ export interface ChangePointGroup { + id: string; group: ChangePointGroupItem[]; docCount: number; pValue: number | null; + histogram?: ChangePointHistogramItem[]; } diff --git a/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/actions.ts b/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/actions.ts index 938c765d8e0d2..e050946a489be 100644 --- a/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/actions.ts +++ b/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/actions.ts @@ -5,12 +5,18 @@ * 2.0. */ -import type { ChangePoint, ChangePointHistogram, ChangePointGroup } from '@kbn/ml-agg-utils'; +import type { + ChangePoint, + ChangePointHistogram, + ChangePointGroup, + ChangePointGroupHistogram, +} from '@kbn/ml-agg-utils'; export const API_ACTION_NAME = { ADD_CHANGE_POINTS: 'add_change_points', ADD_CHANGE_POINTS_HISTOGRAM: 'add_change_points_histogram', ADD_CHANGE_POINTS_GROUP: 'add_change_point_group', + ADD_CHANGE_POINTS_GROUP_HISTOGRAM: 'add_change_point_group_histogram', ADD_ERROR: 'add_error', RESET: 'reset', UPDATE_LOADING_STATE: 'update_loading_state', @@ -57,6 +63,20 @@ export function addChangePointsGroupAction(payload: ApiActionAddChangePointsGrou }; } +interface ApiActionAddChangePointsGroupHistogram { + type: typeof API_ACTION_NAME.ADD_CHANGE_POINTS_GROUP_HISTOGRAM; + payload: ChangePointGroupHistogram[]; +} + +export function addChangePointsGroupHistogramAction( + payload: ApiActionAddChangePointsGroupHistogram['payload'] +): ApiActionAddChangePointsGroupHistogram { + return { + type: API_ACTION_NAME.ADD_CHANGE_POINTS_GROUP_HISTOGRAM, + payload, + }; +} + interface ApiActionAddError { type: typeof API_ACTION_NAME.ADD_ERROR; payload: string; @@ -99,6 +119,7 @@ export type AiopsExplainLogRateSpikesApiAction = | ApiActionAddChangePoints | ApiActionAddChangePointsGroup | ApiActionAddChangePointsHistogram + | ApiActionAddChangePointsGroupHistogram | ApiActionAddError | ApiActionReset | ApiActionUpdateLoadingState; diff --git a/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/index.ts b/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/index.ts index dbc6be43766c6..5628b509980ad 100644 --- a/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/index.ts +++ b/x-pack/plugins/aiops/common/api/explain_log_rate_spikes/index.ts @@ -8,6 +8,7 @@ export { addChangePointsAction, addChangePointsGroupAction, + addChangePointsGroupHistogramAction, addChangePointsHistogramAction, addErrorAction, resetAction, diff --git a/x-pack/plugins/aiops/common/api/stream_reducer.ts b/x-pack/plugins/aiops/common/api/stream_reducer.ts index ff275d1414e91..690db961f5121 100644 --- a/x-pack/plugins/aiops/common/api/stream_reducer.ts +++ b/x-pack/plugins/aiops/common/api/stream_reducer.ts @@ -51,6 +51,15 @@ export function streamReducer( return { ...state, changePoints }; case API_ACTION_NAME.ADD_CHANGE_POINTS_GROUP: return { ...state, changePointsGroups: action.payload }; + case API_ACTION_NAME.ADD_CHANGE_POINTS_GROUP_HISTOGRAM: + const changePointsGroups = state.changePointsGroups.map((cpg) => { + const cpHistogram = action.payload.find((h) => h.id === cpg.id); + if (cpHistogram) { + cpg.histogram = cpHistogram.histogram; + } + return cpg; + }); + return { ...state, changePointsGroups }; case API_ACTION_NAME.ADD_ERROR: return { ...state, errors: [...state.errors, action.payload] }; case API_ACTION_NAME.RESET: 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 350ab9f2e0205..b317ac6f2fed8 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 @@ -127,7 +127,7 @@ export const ExplainLogRateSpikesAnalysis: FC }, []); const groupTableItems = useMemo(() => { - const tableItems = data.changePointsGroups.map(({ group, docCount, pValue }, index) => { + const tableItems = data.changePointsGroups.map(({ id, group, docCount, histogram, pValue }) => { const sortedGroup = group.sort((a, b) => a.fieldName > b.fieldName ? 1 : b.fieldName > a.fieldName ? -1 : 0 ); @@ -144,11 +144,12 @@ export const ExplainLogRateSpikesAnalysis: FC }); return { - id: index, + id, docCount, pValue, group: dedupedGroup, repeatedValues, + histogram, }; }); diff --git a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx index a046250db20b2..37563fd2d43a0 100644 --- a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx +++ b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx @@ -24,7 +24,11 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import type { ChangePoint } from '@kbn/ml-agg-utils'; + import { useEuiTheme } from '../../hooks/use_eui_theme'; + +import { MiniHistogram } from '../mini_histogram'; + import { SpikeAnalysisTable } from './spike_analysis_table'; const NARROW_COLUMN_WIDTH = '120px'; @@ -36,11 +40,12 @@ const DEFAULT_SORT_FIELD = 'pValue'; const DEFAULT_SORT_DIRECTION = 'asc'; interface GroupTableItem { - id: number; + id: string; docCount: number; pValue: number | null; group: Record; repeatedValues: Record; + histogram: ChangePoint['histogram']; } interface SpikeAnalysisTableProps { @@ -196,6 +201,39 @@ export const SpikeAnalysisGroupsTable: FC = ({ sortable: false, textOnly: true, }, + { + 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnLogRate', + width: NARROW_COLUMN_WIDTH, + field: 'pValue', + name: ( + + <> + + + + + ), + render: (_, { histogram, id }) => ( + + ), + sortable: false, + }, { 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnPValue', width: NARROW_COLUMN_WIDTH, @@ -226,9 +264,12 @@ export const SpikeAnalysisGroupsTable: FC = ({ { 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnDocCount', field: 'docCount', - name: i18n.translate('xpack.aiops.correlations.spikeAnalysisTableGroups.docCountLabel', { - defaultMessage: 'Doc count', - }), + name: i18n.translate( + 'xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.docCountLabel', + { + defaultMessage: 'Doc count', + } + ), sortable: true, width: '20%', }, @@ -281,6 +322,7 @@ export const SpikeAnalysisGroupsTable: FC = ({ compressed columns={columns} items={pageOfItems} + itemId="id" itemIdToExpandedRowMap={itemIdToExpandedRowMap} onChange={onChange} pagination={pagination} 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 a6fecc0e1a870..48ea2dbddb1c3 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 @@ -18,10 +18,12 @@ import type { DataRequestHandlerContext } from '@kbn/data-plugin/server'; import { streamFactory } from '@kbn/aiops-utils'; import type { ChangePoint, NumericChartData, NumericHistogramField } from '@kbn/ml-agg-utils'; import { fetchHistogramsForFields } from '@kbn/ml-agg-utils'; +import { stringHash } from '@kbn/ml-string-hash'; import { addChangePointsAction, addChangePointsGroupAction, + addChangePointsGroupHistogramAction, addChangePointsHistogramAction, aiopsExplainLogRateSpikesSchema, addErrorAction, @@ -216,6 +218,21 @@ export const defineExplainLogRateSpikesRoute = ( return; } + const histogramFields: [NumericHistogramField] = [ + { fieldName: request.body.timeFieldName, type: KBN_FIELD_TYPES.DATE }, + ]; + + const [overallTimeSeries] = (await fetchHistogramsForFields( + client, + request.body.index, + { match_all: {} }, + // fields + histogramFields, + // samplerShardSize + -1, + undefined + )) as [NumericChartData]; + if (groupingEnabled) { // To optimize the `frequent_items` query, we identify duplicate change points by count attributes. // Note this is a compromise and not 100% accurate because there could be change points that @@ -325,27 +342,40 @@ export const defineExplainLogRateSpikesRoute = ( }); changePointGroups.push( - ...missingChangePoints.map((cp) => { + ...missingChangePoints.map(({ fieldName, fieldValue, doc_count: docCount, pValue }) => { const duplicates = groupedChangePoints.find((d) => - d.group.some( - (dg) => dg.fieldName === cp.fieldName && dg.fieldValue === cp.fieldValue - ) + d.group.some((dg) => dg.fieldName === fieldName && dg.fieldValue === fieldValue) ); if (duplicates !== undefined) { return { + id: `${stringHash( + JSON.stringify( + duplicates.group.map((d) => ({ + fieldName: d.fieldName, + fieldValue: d.fieldValue, + })) + ) + )}`, group: duplicates.group.map((d) => ({ fieldName: d.fieldName, fieldValue: d.fieldValue, duplicate: false, })), - docCount: cp.doc_count, - pValue: cp.pValue, + docCount, + pValue, }; } else { return { - group: [{ fieldName: cp.fieldName, fieldValue: cp.fieldValue, duplicate: false }], - docCount: cp.doc_count, - pValue: cp.pValue, + id: `${stringHash(JSON.stringify({ fieldName, fieldValue }))}`, + group: [ + { + fieldName, + fieldValue, + duplicate: false, + }, + ], + docCount, + pValue, }; } }) @@ -358,22 +388,62 @@ export const defineExplainLogRateSpikesRoute = ( if (maxItems > 1) { push(addChangePointsGroupAction(changePointGroups)); } - } - const histogramFields: [NumericHistogramField] = [ - { fieldName: request.body.timeFieldName, type: KBN_FIELD_TYPES.DATE }, - ]; + if (changePointGroups) { + await asyncForEach(changePointGroups, async (cpg, index) => { + const histogramQuery = { + bool: { + filter: cpg.group.map((d) => ({ + term: { [d.fieldName]: d.fieldValue }, + })), + }, + }; - const [overallTimeSeries] = (await fetchHistogramsForFields( - client, - request.body.index, - { match_all: {} }, - // fields - histogramFields, - // samplerShardSize - -1, - undefined - )) as [NumericChartData]; + const [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 + )) as [NumericChartData]; + + 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_change_point: current.doc_count, + doc_count_overall: Math.max(0, o.doc_count - current.doc_count), + }; + }) ?? []; + + push( + addChangePointsGroupHistogramAction([ + { + id: cpg.id, + histogram, + }, + ]) + ); + }); + } + } // time series filtered by fields if (changePoints) { diff --git a/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.test.ts b/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.test.ts index 1ff92181dee96..5f2125a583db7 100644 --- a/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.test.ts +++ b/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.test.ts @@ -11,6 +11,7 @@ import { getFieldValuePairCounts, markDuplicates } from './get_simple_hierarchic const changePointGroups: ChangePointGroup[] = [ { + id: 'group-1', group: [ { fieldName: 'custom_field.keyword', @@ -25,6 +26,7 @@ const changePointGroups: ChangePointGroup[] = [ pValue: 0.01, }, { + id: 'group-2', group: [ { fieldName: 'custom_field.keyword', @@ -64,6 +66,7 @@ describe('get_simple_hierarchical_tree', () => { expect(markedDuplicates).toEqual([ { + id: 'group-1', group: [ { fieldName: 'custom_field.keyword', @@ -80,6 +83,7 @@ describe('get_simple_hierarchical_tree', () => { pValue: 0.01, }, { + id: 'group-2', group: [ { fieldName: 'custom_field.keyword', diff --git a/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.ts b/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.ts index bebbb1302376d..9f39d1eb11f68 100644 --- a/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.ts +++ b/x-pack/plugins/aiops/server/routes/queries/get_simple_hierarchical_tree.ts @@ -8,6 +8,7 @@ // import { omit, uniq } from 'lodash'; import type { ChangePointGroup, FieldValuePair } from '@kbn/ml-agg-utils'; +import { stringHash } from '@kbn/ml-string-hash'; import type { ItemsetResult } from './fetch_frequent_items'; @@ -230,9 +231,13 @@ export function getSimpleHierarchicalTreeLeaves( leaves: ChangePointGroup[], level = 1 ) { - // console.log(`${'-'.repeat(level)} ${tree.name} ${tree.children.length}`); if (tree.children.length === 0) { - leaves.push({ group: tree.set, docCount: tree.docCount, pValue: tree.pValue }); + leaves.push({ + id: `${stringHash(JSON.stringify(tree.set))}`, + group: tree.set, + docCount: tree.docCount, + pValue: tree.pValue, + }); } else { for (const child of tree.children) { const newLeaves = getSimpleHierarchicalTreeLeaves(child, [], level + 1); From cb2813579b000d66a78a653e265ba5408fd654ec Mon Sep 17 00:00:00 2001 From: Rickyanto Ang Date: Tue, 20 Sep 2022 12:40:53 -0700 Subject: [PATCH 05/55] removed beta tag on session view component (#141145) --- .../session_view/public/components/session_view/index.tsx | 6 +----- .../session_view/public/components/session_view/styles.ts | 7 +------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx index 01f072f5c52b5..07626d090bd2b 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx @@ -13,7 +13,6 @@ import { EuiPanel, EuiHorizontalRule, EuiFlexGroup, - EuiBetaBadge, EuiButtonIcon, EuiToolTip, } from '@elastic/eui'; @@ -40,7 +39,7 @@ import { useFetchGetTotalIOBytes, } from './hooks'; import { LOCAL_STORAGE_DISPLAY_OPTIONS_KEY } from '../../../common/constants'; -import { BETA, REFRESH_SESSION, TOGGLE_TTY_PLAYER, DETAIL_PANEL } from './translations'; +import { REFRESH_SESSION, TOGGLE_TTY_PLAYER, DETAIL_PANEL } from './translations'; /** * The main wrapper component for the session view. @@ -259,9 +258,6 @@ export const SessionView = ({
- - - { const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { - const { border, colors, size } = euiTheme; + const { border, size } = euiTheme; // 118px = Session View Toolbar height + Close Session button height + spacing margin at the bottom const sessionView: CSSObject = { @@ -55,17 +55,12 @@ export const useStyles = ({ height = 500, isFullScreen }: StylesDeps) => { }, }; - const betaBadge: CSSObject = { - backgroundColor: `${colors.emptyShade}`, - }; - return { processTree, detailPanel, nonGrowGroup, resizeHandle, sessionViewerComponent, - betaBadge, }; }, [euiTheme, isFullScreen, height, euiVars]); From a956266f3e60d0ae3bcfb65e143075b9750a5fe8 Mon Sep 17 00:00:00 2001 From: Joseph McElroy Date: Tue, 20 Sep 2022 20:46:49 +0100 Subject: [PATCH 06/55] [Enterprise Search] [Behavioural Analytics] Fix DSN URL on Integration Page (#141123) * fix dsn url --- .../analytics_collection_integrate.test.tsx | 17 ++++++++++++++--- .../analytics_collection_integrate.tsx | 6 +++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.test.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.test.tsx index f46454e45eb82..8d07e3aac6674 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.test.tsx @@ -9,9 +9,9 @@ import '../../../__mocks__/shallow_useeffect.mock'; import React from 'react'; -import { shallow } from 'enzyme'; +import { mount } from 'enzyme'; -import { EuiCodeBlock } from '@elastic/eui'; +import { EuiCodeBlock, EuiDescriptionListDescription } from '@elastic/eui'; import { AnalyticsCollection } from '../../../../../common/types/analytics'; @@ -29,7 +29,18 @@ describe('AnalyticsCollectionIntegrate', () => { }); it('renders', () => { - const wrapper = shallow(); + const wrapper = mount(); expect(wrapper.find(EuiCodeBlock)).toHaveLength(2); + expect(wrapper.find(EuiDescriptionListDescription).get(0)).toMatchInlineSnapshot(` + + example + + `); + + expect(wrapper.find(EuiDescriptionListDescription).get(1)).toMatchInlineSnapshot(` + + /analytics/api/collections/example + + `); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx index ff5cdf9c5fee1..36b527097a304 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx @@ -28,7 +28,7 @@ interface AnalyticsCollectionIntegrateProps { export const AnalyticsCollectionIntegrate: React.FC = ({ collection, }) => { - const analyticsDNSUrl = getEnterpriseSearchUrl(`/analytics/${collection.name}`); + const analyticsDNSUrl = getEnterpriseSearchUrl(`/analytics/api/collections/${collection.name}`); const credentials = [ { title: i18n.translate( @@ -111,9 +111,9 @@ export const AnalyticsCollectionIntegrate: React.FC - {`window.elasticAnalytics.trackEvent("ResultClick", { + {`window.elasticAnalytics.trackEvent("click", { title: "Website Analytics", - url: "www.elasitc.co/analytics/website" + url: "www.elastic.co/analytics/overview" })`} From ab0e2fbb8e4d0c489b2238afda1f9c4ef6d2953d Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 20 Sep 2022 16:06:13 -0400 Subject: [PATCH 07/55] fix(slo): use spaceId for pipeline names (#141133) --- .../plugins/observability/server/assets/constants.ts | 8 +++++--- .../observability/server/routes/register_routes.ts | 4 ++++ .../server/services/slo/resource_installer.test.ts | 12 +++++++----- .../server/services/slo/resource_installer.ts | 11 +++++------ .../apm_transaction_duration.test.ts.snap | 2 +- .../apm_transaction_error_rate.test.ts.snap | 2 +- .../transform_generators/apm_transaction_duration.ts | 4 ++-- .../apm_transaction_error_rate.ts | 4 ++-- 8 files changed, 27 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/observability/server/assets/constants.ts b/x-pack/plugins/observability/server/assets/constants.ts index ea96f7a3b5763..4c0cc0e2e6f83 100644 --- a/x-pack/plugins/observability/server/assets/constants.ts +++ b/x-pack/plugins/observability/server/assets/constants.ts @@ -5,12 +5,14 @@ * 2.0. */ -export const SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME = 'observability-slo-mappings'; -export const SLO_COMPONENT_TEMPLATE_SETTINGS_NAME = 'observability-slo-settings'; +export const SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME = 'slo-observability.sli-mappings'; +export const SLO_COMPONENT_TEMPLATE_SETTINGS_NAME = 'slo-observability.sli-settings'; export const SLO_INDEX_TEMPLATE_NAME = 'slo-observability.sli'; -export const SLO_INGEST_PIPELINE_NAME = 'observability-slo-monthly-index'; export const SLO_RESOURCES_VERSION = 1; +export const getSLOIngestPipelineName = (spaceId: string) => + `${SLO_INDEX_TEMPLATE_NAME}.monthly-${spaceId}`; + export const getSLODestinationIndexName = (spaceId: string) => `${SLO_INDEX_TEMPLATE_NAME}-v${SLO_RESOURCES_VERSION}-${spaceId}`; diff --git a/x-pack/plugins/observability/server/routes/register_routes.ts b/x-pack/plugins/observability/server/routes/register_routes.ts index 1a1fdf220afb2..e0e9e94f5cb21 100644 --- a/x-pack/plugins/observability/server/routes/register_routes.ts +++ b/x-pack/plugins/observability/server/routes/register_routes.ts @@ -70,6 +70,10 @@ export function registerRoutes({ spacesService, })) as any; + if (data === undefined) { + return response.noContent(); + } + return response.ok({ body: data }); } catch (error) { if (error instanceof ObservabilityError) { diff --git a/x-pack/plugins/observability/server/services/slo/resource_installer.test.ts b/x-pack/plugins/observability/server/services/slo/resource_installer.test.ts index 40dc0e46022bc..f8746f38cd246 100644 --- a/x-pack/plugins/observability/server/services/slo/resource_installer.test.ts +++ b/x-pack/plugins/observability/server/services/slo/resource_installer.test.ts @@ -9,14 +9,15 @@ import { IngestGetPipelineResponse } from '@elastic/elasticsearch/lib/api/typesW import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { loggerMock } from '@kbn/logging-mocks'; import { + getSLOIngestPipelineName, SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME, SLO_COMPONENT_TEMPLATE_SETTINGS_NAME, SLO_INDEX_TEMPLATE_NAME, - SLO_INGEST_PIPELINE_NAME, SLO_RESOURCES_VERSION, } from '../../assets/constants'; import { DefaultResourceInstaller } from './resource_installer'; +const SPACE_ID = 'space-id'; describe('resourceInstaller', () => { describe("when the common resources don't exist", () => { it('installs the common resources', async () => { @@ -25,7 +26,7 @@ describe('resourceInstaller', () => { const installer = new DefaultResourceInstaller( mockClusterClient, loggerMock.create(), - 'space-id' + SPACE_ID ); await installer.ensureCommonResourcesInstalled(); @@ -43,7 +44,7 @@ describe('resourceInstaller', () => { expect.objectContaining({ name: SLO_INDEX_TEMPLATE_NAME }) ); expect(mockClusterClient.ingest.putPipeline).toHaveBeenCalledWith( - expect.objectContaining({ id: SLO_INGEST_PIPELINE_NAME }) + expect.objectContaining({ id: getSLOIngestPipelineName(SPACE_ID) }) ); }); }); @@ -53,12 +54,13 @@ describe('resourceInstaller', () => { const mockClusterClient = elasticsearchServiceMock.createElasticsearchClient(); mockClusterClient.indices.existsIndexTemplate.mockResponseOnce(true); mockClusterClient.ingest.getPipeline.mockResponseOnce({ - [SLO_INGEST_PIPELINE_NAME]: { _meta: { version: SLO_RESOURCES_VERSION } }, + // @ts-ignore _meta not typed properly + [getSLOIngestPipelineName(SPACE_ID)]: { _meta: { version: SLO_RESOURCES_VERSION } }, } as IngestGetPipelineResponse); const installer = new DefaultResourceInstaller( mockClusterClient, loggerMock.create(), - 'space-id' + SPACE_ID ); await installer.ensureCommonResourcesInstalled(); diff --git a/x-pack/plugins/observability/server/services/slo/resource_installer.ts b/x-pack/plugins/observability/server/services/slo/resource_installer.ts index 280183d70459a..8ed8108b3c4b7 100644 --- a/x-pack/plugins/observability/server/services/slo/resource_installer.ts +++ b/x-pack/plugins/observability/server/services/slo/resource_installer.ts @@ -13,10 +13,10 @@ import type { import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { + getSLOIngestPipelineName, SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME, SLO_COMPONENT_TEMPLATE_SETTINGS_NAME, SLO_INDEX_TEMPLATE_NAME, - SLO_INGEST_PIPELINE_NAME, SLO_RESOURCES_VERSION, } from '../../assets/constants'; import { getSLOMappingsTemplate } from '../../assets/component_templates/slo_mappings_template'; @@ -64,7 +64,7 @@ export class DefaultResourceInstaller implements ResourceInstaller { await this.createOrUpdateIngestPipelineTemplate( getSLOPipelineTemplate( - SLO_INGEST_PIPELINE_NAME, + getSLOIngestPipelineName(this.spaceId), this.getPipelinePrefix(SLO_RESOURCES_VERSION, this.spaceId) ) ); @@ -87,13 +87,12 @@ export class DefaultResourceInstaller implements ResourceInstaller { let ingestPipelineExists = false; try { - const pipeline = await this.esClient.ingest.getPipeline({ - id: SLO_INGEST_PIPELINE_NAME, - }); + const pipelineName = getSLOIngestPipelineName(this.spaceId); + const pipeline = await this.esClient.ingest.getPipeline({ id: pipelineName }); ingestPipelineExists = // @ts-ignore _meta is not defined on the type - pipeline && pipeline[SLO_INGEST_PIPELINE_NAME]._meta.version === SLO_RESOURCES_VERSION; + pipeline && pipeline[pipelineName]._meta.version === SLO_RESOURCES_VERSION; } catch (err) { return false; } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap index 5cdda1a532b44..29ce4877b6b34 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap @@ -21,7 +21,7 @@ Object { }, "dest": Object { "index": "slo-observability.sli-v1-my-namespace", - "pipeline": "observability-slo-monthly-index", + "pipeline": "slo-observability.sli.monthly-my-namespace", }, "frequency": "1m", "pivot": Object { diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap index ecebd37a4c7fc..58ed238fcf0a7 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap @@ -21,7 +21,7 @@ Object { }, "dest": Object { "index": "slo-observability.sli-v1-my-namespace", - "pipeline": "observability-slo-monthly-index", + "pipeline": "slo-observability.sli.monthly-my-namespace", }, "frequency": "1m", "pivot": Object { diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts index 2117ccb62625b..9c0a5aafc693f 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts @@ -12,8 +12,8 @@ import { } from '@elastic/elasticsearch/lib/api/types'; import { getSLODestinationIndexName, + getSLOIngestPipelineName, getSLOTransformId, - SLO_INGEST_PIPELINE_NAME, } from '../../../assets/constants'; import { getSLOTransformTemplate } from '../../../assets/transform_templates/slo_transform_template'; import { @@ -106,7 +106,7 @@ export class ApmTransactionDurationTransformGenerator implements TransformGenera private buildDestination(slo: APMTransactionDurationSLO, spaceId: string) { return { - pipeline: SLO_INGEST_PIPELINE_NAME, + pipeline: getSLOIngestPipelineName(spaceId), index: getSLODestinationIndexName(spaceId), }; } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts index 5e9bc30c060ec..6fa806e72e197 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts @@ -14,8 +14,8 @@ import { getSLOTransformTemplate } from '../../../assets/transform_templates/slo import { TransformGenerator } from '.'; import { getSLODestinationIndexName, + getSLOIngestPipelineName, getSLOTransformId, - SLO_INGEST_PIPELINE_NAME, } from '../../../assets/constants'; import { apmTransactionErrorRateSLOSchema, @@ -108,7 +108,7 @@ export class ApmTransactionErrorRateTransformGenerator implements TransformGener private buildDestination(slo: APMTransactionErrorRateSLO, spaceId: string) { return { - pipeline: SLO_INGEST_PIPELINE_NAME, + pipeline: getSLOIngestPipelineName(spaceId), index: getSLODestinationIndexName(spaceId), }; } From b4467665cba59268377e28c5b59e27d51a37fe80 Mon Sep 17 00:00:00 2001 From: Khristinin Nikita Date: Tue, 20 Sep 2022 22:10:02 +0200 Subject: [PATCH 08/55] Skip test (#141157) --- .../cypress/e2e/detection_alerts/enrichments.cy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/enrichments.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/enrichments.cy.ts index ff1c4f6acb177..ca5951e2456c1 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/enrichments.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/enrichments.cy.ts @@ -30,7 +30,7 @@ import { login, visit } from '../../tasks/login'; import { ALERTS_URL } from '../../urls/navigation'; -describe('Enrichment', () => { +describe.skip('Enrichment', () => { before(() => { cleanKibana(); esArchiverLoad('risky_users'); From 348b7158f99c15c138c80564573ff7f0596cf403 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 20 Sep 2022 16:42:03 -0400 Subject: [PATCH 09/55] [Enterprise Search] Allow user to customize name and description of connector indices (#141151) --- .../common/types/connectors.ts | 1 + .../__mocks__/search_indices.mock.ts | 2 + .../__mocks__/view_index.mock.ts | 2 + ...onnector_name_and_description_api_logic.ts | 42 ++++++ .../{total_stats.tsx => api_total_stats.tsx} | 16 +-- .../connector/connector_configuration.tsx | 12 ++ .../connector_name_and_description.tsx | 84 +++++++++++ .../connector_name_and_description_form.tsx | 97 +++++++++++++ .../connector_name_and_description_logic.ts | 136 ++++++++++++++++++ .../connector/connector_overview_panels.tsx | 31 +--- .../connector_name_and_description.tsx | 83 ----------- .../native_connector_configuration.tsx | 27 ++-- .../search_index/connector_total_stats.tsx | 99 +++++++++++++ .../search_index/crawler_total_stats.tsx | 53 +++++-- .../name_and_description_stats.tsx | 74 ++++++++++ .../components/search_index/overview.tsx | 26 +--- .../applications/shared/constants/labels.ts | 8 ++ .../lib/connectors/add_connector.test.ts | 3 + .../server/lib/connectors/add_connector.ts | 1 + .../update_connector_name_and_description.ts | 40 ++++++ .../routes/enterprise_search/connectors.ts | 25 ++++ .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 24 files changed, 697 insertions(+), 168 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/update_connector_name_and_description_api_logic.ts rename x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/{total_stats.tsx => api_total_stats.tsx} (85%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_form.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/connector_name_and_description.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector_total_stats.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/name_and_description_stats.tsx create mode 100644 x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_name_and_description.ts diff --git a/x-pack/plugins/enterprise_search/common/types/connectors.ts b/x-pack/plugins/enterprise_search/common/types/connectors.ts index 655322e86f1b5..44105cf34c0c2 100644 --- a/x-pack/plugins/enterprise_search/common/types/connectors.ts +++ b/x-pack/plugins/enterprise_search/common/types/connectors.ts @@ -41,6 +41,7 @@ export interface IngestPipelineParams { export interface Connector { api_key_id: string | null; configuration: ConnectorConfiguration; + description: string | null; error: string | null; id: string; index_name: string; 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 457f37f5d13a9..b8063d57ff984 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 @@ -27,6 +27,7 @@ export const indices: ElasticsearchIndexWithIngestion[] = [ connector: { api_key_id: null, configuration: { foo: { label: 'bar', value: 'barbar' } }, + description: null, error: null, id: '2', index_name: 'connector', @@ -76,6 +77,7 @@ export const indices: ElasticsearchIndexWithIngestion[] = [ connector: { api_key_id: null, configuration: { foo: { label: 'bar', value: 'barbar' } }, + description: null, error: null, id: '4', index_name: 'connector-crawler', 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 52901d3e067c9..db4080f18e7a4 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 @@ -36,6 +36,7 @@ export const connectorIndex: ConnectorViewIndex = { connector: { api_key_id: null, configuration: { foo: { label: 'bar', value: 'barbar' } }, + description: null, error: null, id: '2', index_name: 'connector', @@ -91,6 +92,7 @@ export const connectorCrawlerIndex: CrawlerViewIndex = { connector: { api_key_id: null, configuration: { foo: { label: 'bar', value: 'barbar' } }, + description: null, error: null, id: '4', index_name: 'connector-crawler', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/update_connector_name_and_description_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/update_connector_name_and_description_api_logic.ts new file mode 100644 index 0000000000000..caf19f80f040a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/update_connector_name_and_description_api_logic.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Connector } from '../../../../../common/types/connectors'; +import { createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export type PutConnectorNameAndDescriptionArgs = Partial< + Pick +> & { + connectorId: string; + indexName: string; +}; + +export type PutConnectorNameAndDescriptionResponse = Partial< + Pick +> & { + indexName: string; +}; + +export const putConnectorNameAndDescription = async ({ + connectorId, + description, + indexName, + name, +}: PutConnectorNameAndDescriptionArgs) => { + const route = `/internal/enterprise_search/connectors/${connectorId}/name_and_description`; + + await HttpLogic.values.http.put(route, { + body: JSON.stringify({ description, name }), + }); + return { description, indexName, name }; +}; + +export const ConnectorNameAndDescriptionApiLogic = createApiLogic( + ['content', 'connector_name_and_description_api_logic'], + putConnectorNameAndDescription +); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/total_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/api_total_stats.tsx similarity index 85% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/total_stats.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/api_total_stats.tsx index dd55dd399392c..38f963d6fa1ce 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/total_stats.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/api_total_stats.tsx @@ -15,13 +15,7 @@ import { i18n } from '@kbn/i18n'; import { OverviewLogic } from './overview.logic'; -interface TotalStatsProps { - additionalItems?: EuiStatProps[]; - ingestionType: string; - lastUpdated?: string; -} - -export const TotalStats: React.FC = ({ ingestionType, additionalItems = [] }) => { +export const ApiTotalStats: React.FC = () => { const { indexData, isError, isLoading } = useValues(OverviewLogic); const documentCount = indexData?.count ?? 0; const hideStats = isLoading || isError; @@ -35,7 +29,12 @@ export const TotalStats: React.FC = ({ ingestionType, additiona } ), isLoading: hideStats, - title: ingestionType, + title: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndex.totalStats.apiIngestionMethodLabel', + { + defaultMessage: 'API', + } + ), }, { description: i18n.translate( @@ -47,7 +46,6 @@ export const TotalStats: React.FC = ({ ingestionType, additiona isLoading: hideStats, title: documentCount, }, - ...additionalItems, ]; return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx index 1ef66afa3106f..233825d6af135 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx @@ -43,6 +43,7 @@ import { SearchIndexTabId } from '../search_index'; import { ApiKeyConfig } from './api_key_configuration'; import { ConnectorConfigurationConfig } from './connector_configuration_config'; +import { ConnectorNameAndDescription } from './connector_name_and_description/connector_name_and_description'; import { NativeConnectorConfiguration } from './native_connector_configuration/native_connector_configuration'; export const ConnectorConfiguration: React.FC = () => { @@ -84,6 +85,17 @@ export const ConnectorConfiguration: React.FC = () => { ), titleSize: 'xs', }, + { + children: , + status: indexData.connector.description ? 'complete' : 'incomplete', + title: i18n.translate( + 'xpack.enterpriseSearch.content.indices.configurationConnector.steps.nameAndDescriptionTitle', + { + defaultMessage: 'Name and description', + } + ), + titleSize: 'xs', + }, { children: ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description.tsx new file mode 100644 index 0000000000000..d75482e25e784 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description.tsx @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { useActions, useValues } from 'kea'; + +import { + EuiButton, + EuiDescriptionList, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiText, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { NAME_LABEL, DESCRIPTION_LABEL, EDIT_BUTTON_LABEL } from '../../../../../shared/constants'; + +import { isConnectorIndex } from '../../../../utils/indices'; +import { IndexViewLogic } from '../../index_view_logic'; + +import { ConnectorNameAndDescriptionForm } from './connector_name_and_description_form'; +import { ConnectorNameAndDescriptionLogic } from './connector_name_and_description_logic'; + +export const ConnectorNameAndDescription: React.FC = () => { + const { index: indexData } = useValues(IndexViewLogic); + const { + isEditing, + nameAndDescription: { name, description }, + } = useValues(ConnectorNameAndDescriptionLogic); + const { setIsEditing } = useActions(ConnectorNameAndDescriptionLogic); + + if (!isConnectorIndex(indexData)) { + return <>; + } + + return ( + + + + {i18n.translate( + 'xpack.enterpriseSearch.content.indices.configurationConnector.nameAndDescriptionForm.description', + { + defaultMessage: + 'By naming and describing this connector your colleagues and wider team will know what this connector is meant for.', + } + )} + + + + {isEditing ? ( + + ) : ( + <> + + + + + setIsEditing(!isEditing)}>{EDIT_BUTTON_LABEL} + + + + )} + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_form.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_form.tsx new file mode 100644 index 0000000000000..33ea50ff8c6d6 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_form.tsx @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { useActions, useValues } from 'kea'; + +import { + EuiButton, + EuiButtonEmpty, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiFormRow, + EuiTextArea, +} from '@elastic/eui'; + +import { Status } from '../../../../../../../common/types/api'; +import { + NAME_LABEL, + DESCRIPTION_LABEL, + SAVE_BUTTON_LABEL, + CANCEL_BUTTON_LABEL, +} from '../../../../../shared/constants'; +import { ConnectorNameAndDescriptionApiLogic } from '../../../../api/connector/update_connector_name_and_description_api_logic'; +import { isConnectorIndex } from '../../../../utils/indices'; +import { IndexViewLogic } from '../../index_view_logic'; + +import { ConnectorNameAndDescriptionLogic } from './connector_name_and_description_logic'; + +export const ConnectorNameAndDescriptionForm: React.FC = () => { + const { index: indexData } = useValues(IndexViewLogic); + const { status } = useValues(ConnectorNameAndDescriptionApiLogic); + const { + localNameAndDescription: { name, description }, + } = useValues(ConnectorNameAndDescriptionLogic); + const { saveNameAndDescription, setIsEditing, updateLocalNameAndDescription } = useActions( + ConnectorNameAndDescriptionLogic + ); + + if (!isConnectorIndex(indexData)) { + return <>; + } + + return ( + { + event.preventDefault(); + saveNameAndDescription(); + }} + component="form" + > + + { + updateLocalNameAndDescription({ name: event.target.value }); + }} + /> + + + { + updateLocalNameAndDescription({ description: event.target.value }); + }} + /> + + + + + + {SAVE_BUTTON_LABEL} + + + + { + setIsEditing(false); + }} + > + {CANCEL_BUTTON_LABEL} + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_logic.ts new file mode 100644 index 0000000000000..a18b71320ca0b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_name_and_description/connector_name_and_description_logic.ts @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { kea, MakeLogicType } from 'kea'; + +import { i18n } from '@kbn/i18n'; + +import { Connector } from '../../../../../../../common/types/connectors'; +import { Actions } from '../../../../../shared/api_logic/create_api_logic'; +import { + flashAPIErrors, + flashSuccessToast, + clearFlashMessages, +} from '../../../../../shared/flash_messages'; +import { + ConnectorNameAndDescriptionApiLogic, + PutConnectorNameAndDescriptionArgs, + PutConnectorNameAndDescriptionResponse, +} from '../../../../api/connector/update_connector_name_and_description_api_logic'; +import { + FetchIndexApiLogic, + FetchIndexApiParams, + FetchIndexApiResponse, +} from '../../../../api/index/fetch_index_api_logic'; +import { isConnectorIndex } from '../../../../utils/indices'; + +type NameAndDescription = Partial>; + +type ConnectorNameAndDescriptionActions = Pick< + Actions, + 'apiError' | 'apiSuccess' | 'makeRequest' +> & { + fetchIndexApiSuccess: Actions['apiSuccess']; + saveNameAndDescription: () => void; + setIsEditing(isEditing: boolean): { isEditing: boolean }; + setLocalNameAndDescription(nameAndDescription: NameAndDescription): NameAndDescription; + setNameAndDescription(nameAndDescription: NameAndDescription): NameAndDescription; + updateLocalNameAndDescription(nameAndDescription: NameAndDescription): NameAndDescription; +}; + +interface ConnectorNameAndDescriptionValues { + index: FetchIndexApiResponse; + isEditing: boolean; + localNameAndDescription: NameAndDescription; + nameAndDescription: NameAndDescription; +} + +export const ConnectorNameAndDescriptionLogic = kea< + MakeLogicType +>({ + actions: { + saveNameAndDescription: true, + setIsEditing: (isEditing: boolean) => ({ + isEditing, + }), + setLocalNameAndDescription: (nameAndDescription) => nameAndDescription, + setNameAndDescription: (nameAndDescription) => nameAndDescription, + updateLocalNameAndDescription: (nameAndDescription) => nameAndDescription, + }, + connect: { + actions: [ + ConnectorNameAndDescriptionApiLogic, + ['apiError', 'apiSuccess', 'makeRequest'], + FetchIndexApiLogic, + ['apiSuccess as fetchIndexApiSuccess'], + ], + values: [FetchIndexApiLogic, ['data as index']], + }, + events: ({ actions, values }) => ({ + afterMount: () => + actions.setNameAndDescription(isConnectorIndex(values.index) ? values.index.connector : {}), + }), + listeners: ({ actions, values }) => ({ + apiError: (error) => flashAPIErrors(error), + apiSuccess: ({ indexName }) => { + flashSuccessToast( + i18n.translate( + 'xpack.enterpriseSearch.content.indices.configurationConnector.configuration.successToast.title', + { defaultMessage: 'Configuration successfully updated' } + ) + ); + FetchIndexApiLogic.actions.makeRequest({ indexName }); + }, + fetchIndexApiSuccess: (index) => { + if (!values.isEditing && isConnectorIndex(index)) { + actions.setNameAndDescription(index.connector); + } + }, + makeRequest: () => clearFlashMessages(), + saveNameAndDescription: () => { + if (isConnectorIndex(values.index)) { + actions.makeRequest({ + connectorId: values.index.connector.id, + indexName: values.index.connector.index_name, + ...values.localNameAndDescription, + }); + } + }, + setIsEditing: (isEditing) => { + if (isEditing) { + actions.setLocalNameAndDescription(values.nameAndDescription); + } + }, + }), + path: ['enterprise_search', 'content', 'connector_name_and_description'], + reducers: () => ({ + isEditing: [ + false, + { + apiSuccess: () => false, + setIsEditing: (_, { isEditing }) => isEditing, + }, + ], + localNameAndDescription: [ + {}, + { + setLocalNameAndDescription: (_, nameAndDescription) => nameAndDescription, + updateLocalNameAndDescription: (localNameAndDescription, nameAndDescription) => ({ + ...localNameAndDescription, + ...nameAndDescription, + }), + }, + ], + nameAndDescription: [ + {}, + { + apiSuccess: (_, { description, name }) => ({ description, name }), + setNameAndDescription: (_, nameAndDescription) => nameAndDescription, + }, + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx index a0d1c3d97fe96..78152d64d248b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx @@ -28,8 +28,6 @@ import { import { IndexViewLogic } from '../index_view_logic'; import { SearchIndexTabId } from '../search_index'; -import { NATIVE_CONNECTORS } from './constants'; - const StatusPanel: React.FC<{ ingestionStatus: IngestionStatus }> = ({ ingestionStatus }) => ( { return isConnectorIndex(index) ? ( - - - - - - + connector.serviceType === index.connector.service_type - )?.name ?? - index.connector.service_type ?? - i18n.translate('xpack.enterpriseSearch.connector.connectorTypePanel.unknown.label', { - defaultMessage: 'Unknown', - }) - } + title={index.count} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/connector_name_and_description.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/connector_name_and_description.tsx deleted file mode 100644 index 552d0ce197c87..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/connector_name_and_description.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { useValues } from 'kea'; - -import { - EuiButton, - EuiFieldText, - EuiFlexGroup, - EuiFlexItem, - EuiForm, - EuiFormRow, - EuiText, - EuiTextArea, -} from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; - -import { isConnectorIndex } from '../../../../utils/indices'; -import { IndexViewLogic } from '../../index_view_logic'; -import { NativeConnector } from '../types'; - -interface ConnectorNameAndDescriptionProps { - nativeConnector: NativeConnector; -} - -export const ConnectorNameAndDescription: React.FC = ({ - nativeConnector, -}) => { - const { index: indexData } = useValues(IndexViewLogic); - const { name } = nativeConnector; - return ( - - - - - {i18n.translate( - 'xpack.enterpriseSearch.content.indices.configurationConnector.nameAndDescriptionForm.description', - { - defaultMessage: - 'By naming and describing this connector your colleagues and wider team will know what this connector is meant for.', - } - )} - - - - - - - - - - - - - - - - - {i18n.translate( - 'xpack.enterpriseSearch.content.indices.configurationConnector.nameAndDescriptionForm.submitButtonLabel', - { - defaultMessage: 'Save name and description', - } - )} - - - - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx index aaa85de188985..18aa5a43582b7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/native_connector_configuration/native_connector_configuration.tsx @@ -28,6 +28,7 @@ import { NATIVE_CONNECTOR_ICONS } from '../../../../../../assets/source_icons/na import { hasConfiguredConfiguration } from '../../../../utils/has_configured_configuration'; import { isConnectorIndex } from '../../../../utils/indices'; import { IndexViewLogic } from '../../index_view_logic'; +import { ConnectorNameAndDescription } from '../connector_name_and_description/connector_name_and_description'; import { NATIVE_CONNECTORS } from '../constants'; import { NativeConnectorAdvancedConfiguration } from './native_connector_advanced_configuration'; @@ -49,10 +50,11 @@ export const NativeConnectorConfiguration: React.FC = () => { return <>; } + const hasDescription = !!indexData.connector.description; const hasConfigured = hasConfiguredConfiguration(indexData.connector.configuration); const hasConfiguredAdvanced = indexData.connector.last_synced || indexData.connector.scheduling.enabled; - const hasResearched = hasConfigured || hasConfiguredAdvanced; + const hasResearched = hasDescription || hasConfigured || hasConfiguredAdvanced; const icon = NATIVE_CONNECTOR_ICONS[nativeConnector.serviceType]; return ( @@ -87,18 +89,17 @@ export const NativeConnectorConfiguration: React.FC = () => { ), titleSize: 'xs', }, - /* Commenting this out for a future PR to implement fully */ - // { - // children: , - // status: hasName ? 'complete' : 'incomplete', - // title: i18n.translate( - // 'xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.steps.nameAndDescriptionTitle', - // { - // defaultMessage: 'Name and description', - // } - // ), - // titleSize: 'xs', - // }, + { + children: , + status: hasDescription ? 'complete' : 'incomplete', + title: i18n.translate( + 'xpack.enterpriseSearch.content.indices.configurationConnector.nativeConnector.steps.nameAndDescriptionTitle', + { + defaultMessage: 'Name and description', + } + ), + titleSize: 'xs', + }, { children: ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector_total_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector_total_stats.tsx new file mode 100644 index 0000000000000..2b5ef4cb68df7 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector_total_stats.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useValues } from 'kea'; + +import { + EuiStatProps, + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiStat, + EuiSpacer, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { isConnectorIndex } from '../../utils/indices'; + +import { ConnectorOverviewPanels } from './connector/connector_overview_panels'; +import { NATIVE_CONNECTORS } from './connector/constants'; +import { NameAndDescriptionStats } from './name_and_description_stats'; +import { OverviewLogic } from './overview.logic'; + +export const ConnectorTotalStats: React.FC = () => { + const { indexData, isError, isLoading } = useValues(OverviewLogic); + const hideStats = isLoading || isError; + + if (!isConnectorIndex(indexData)) { + return <>; + } + + const stats: EuiStatProps[] = [ + { + description: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndex.totalStats.ingestionTypeCardLabel', + { + defaultMessage: 'Ingestion type', + } + ), + isLoading: hideStats, + title: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndex.totalStats.connectorIngestionMethodLabel', + { + defaultMessage: 'Connector', + } + ), + }, + { + description: i18n.translate('xpack.enterpriseSearch.connector.connectorTypePanel.title', { + defaultMessage: 'Connector type', + }), + title: + NATIVE_CONNECTORS.find( + (connector) => connector.serviceType === indexData.connector.service_type + )?.name ?? + indexData.connector.service_type ?? + i18n.translate('xpack.enterpriseSearch.connector.connectorTypePanel.unknown.label', { + defaultMessage: 'Unknown', + }), + }, + { + description: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndex.totalStats.languageLabel', + { + defaultMessage: 'Language analyzer', + } + ), + isLoading: hideStats, + title: + indexData.connector.language ?? + i18n.translate('xpack.enterpriseSearch.content.searchIndex.totalStats.noneLabel', { + defaultMessage: 'None', + }), + }, + ]; + + return ( + <> + + + + {stats.map((item, index) => ( + + + + + + ))} + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx index 367932d987900..f396dd19d5385 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler_total_stats.tsx @@ -9,15 +9,34 @@ import React from 'react'; import { useValues } from 'kea'; +import { EuiStatProps, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { CrawlerLogic } from './crawler/crawler_logic'; -import { TotalStats } from './total_stats'; +import { OverviewLogic } from './overview.logic'; export const CrawlerTotalStats: React.FC = () => { const { domains, dataLoading } = useValues(CrawlerLogic); + const { indexData, isError, isLoading } = useValues(OverviewLogic); + const documentCount = indexData?.count ?? 0; + const hideStats = isLoading || isError; - const additionalItems = [ + const stats: EuiStatProps[] = [ + { + description: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndex.totalStats.ingestionTypeCardLabel', + { + defaultMessage: 'Ingestion type', + } + ), + isLoading: hideStats, + title: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndex.totalStats.crawlerIngestionMethodLabel', + { + defaultMessage: 'Crawler', + } + ), + }, { description: i18n.translate( 'xpack.enterpriseSearch.content.searchIndex.totalStats.domainCountCardLabel', @@ -25,20 +44,30 @@ export const CrawlerTotalStats: React.FC = () => { defaultMessage: 'Domain count', } ), - isLoading: dataLoading, + isLoading: dataLoading || hideStats, title: domains.length, }, + { + description: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndex.totalStats.documentCountCardLabel', + { + defaultMessage: 'Document count', + } + ), + isLoading: hideStats, + title: documentCount, + }, ]; return ( - + + {stats.map((item, index) => ( + + + + + + ))} + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/name_and_description_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/name_and_description_stats.tsx new file mode 100644 index 0000000000000..a7f150d24cbf2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/name_and_description_stats.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useValues } from 'kea'; + +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat, EuiStatProps, EuiText } from '@elastic/eui'; + +import { DESCRIPTION_LABEL, NAME_LABEL } from '../../../shared/constants'; +import { generateEncodedPath } from '../../../shared/encode_path_params'; +import { EuiLinkTo } from '../../../shared/react_router_helpers'; +import { SEARCH_INDEX_TAB_PATH } from '../../routes'; +import { isConnectorIndex } from '../../utils/indices'; + +import { IndexNameLogic } from './index_name_logic'; +import { OverviewLogic } from './overview.logic'; +import { SearchIndexTabId } from './search_index'; + +const EditDescription: React.FC<{ label: string; indexName: string }> = ({ label, indexName }) => ( + + {label} + + + Edit + + + +); + +export const NameAndDescriptionStats: React.FC = () => { + const { indexName } = useValues(IndexNameLogic); + const { indexData, isError, isLoading } = useValues(OverviewLogic); + const hideStats = isLoading || isError; + + if (!isConnectorIndex(indexData)) { + return <>; + } + + const stats: EuiStatProps[] = [ + { + description: , + isLoading: hideStats, + title: indexData.connector.name, + }, + { + description: , + isLoading: hideStats, + title: {indexData.connector.description || ''}, + titleElement: 'p', + }, + ]; + + return ( + + {stats.map((item, index) => ( + + + + + + ))} + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx index f30c9a24dda92..56ec6a7563dec 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx @@ -15,14 +15,14 @@ import { i18n } from '@kbn/i18n'; import { isApiIndex, isConnectorIndex, isCrawlerIndex } from '../../utils/indices'; -import { ConnectorOverviewPanels } from './connector/connector_overview_panels'; +import { ApiTotalStats } from './api_total_stats'; +import { ConnectorTotalStats } from './connector_total_stats'; import { CrawlDetailsFlyout } from './crawler/crawl_details_flyout/crawl_details_flyout'; import { CrawlRequestsPanel } from './crawler/crawl_requests_panel/crawl_requests_panel'; import { CrawlerTotalStats } from './crawler_total_stats'; import { GenerateApiKeyPanel } from './generate_api_key_panel'; import { OverviewLogic } from './overview.logic'; import { SyncJobs } from './sync_jobs'; -import { TotalStats } from './total_stats'; export const SearchIndexOverview: React.FC = () => { const { indexData } = useValues(OverviewLogic); @@ -50,24 +50,10 @@ export const SearchIndexOverview: React.FC = () => { )} {isCrawlerIndex(indexData) ? ( + ) : isConnectorIndex(indexData) ? ( + ) : ( - + )} {isApiIndex(indexData) && ( <> @@ -84,8 +70,6 @@ export const SearchIndexOverview: React.FC = () => { )} {isConnectorIndex(indexData) && ( <> - - diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/constants/labels.ts b/x-pack/plugins/enterprise_search/public/applications/shared/constants/labels.ts index 97845b0a8e109..fa982547f7fc5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/constants/labels.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/constants/labels.ts @@ -33,3 +33,11 @@ export const TECHNICAL_PREVIEW_LABEL = i18n.translate( defaultMessage: 'Technical Preview', // title case specifically requested } ); + +export const NAME_LABEL = i18n.translate('xpack.enterpriseSearch.nameLabel', { + defaultMessage: 'Name', +}); + +export const DESCRIPTION_LABEL = i18n.translate('xpack.enterpriseSearch.descriptionLabel', { + defaultMessage: 'Description', +}); 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 d8a0ace2603dd..cad0b3b88e38e 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 @@ -86,6 +86,7 @@ describe('addConnector lib function', () => { document: { api_key_id: null, configuration: {}, + description: null, error: null, index_name: 'index_name', is_native: false, @@ -216,6 +217,7 @@ describe('addConnector lib function', () => { document: { api_key_id: null, configuration: {}, + description: null, error: null, index_name: 'index_name', is_native: true, @@ -268,6 +270,7 @@ describe('addConnector lib function', () => { document: { api_key_id: null, configuration: {}, + description: null, error: null, index_name: 'search-index_name', is_native: false, diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts index 63c4d1834c4f4..1b02dda8d26ad 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts @@ -87,6 +87,7 @@ export const addConnector = async ( const document: ConnectorDocument = { api_key_id: null, configuration: {}, + description: null, error: null, index_name: input.index_name, is_native: input.is_native, diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_name_and_description.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_name_and_description.ts new file mode 100644 index 0000000000000..caca94ee2713a --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/update_connector_name_and_description.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IScopedClusterClient } from '@kbn/core/server'; +import { i18n } from '@kbn/i18n'; + +import { CONNECTORS_INDEX } from '../..'; + +import { Connector, ConnectorDocument } from '../../../common/types/connectors'; + +export const updateConnectorNameAndDescription = async ( + client: IScopedClusterClient, + connectorId: string, + connectorUpdates: Partial> +) => { + const connectorResult = await client.asCurrentUser.get({ + id: connectorId, + index: CONNECTORS_INDEX, + }); + const connector = connectorResult._source; + if (connector) { + const result = await client.asCurrentUser.index({ + document: { ...connector, ...connectorUpdates }, + id: connectorId, + index: CONNECTORS_INDEX, + }); + await client.asCurrentUser.indices.refresh({ index: CONNECTORS_INDEX }); + return result; + } else { + throw new Error( + i18n.translate('xpack.enterpriseSearch.server.connectors.serviceType.error', { + defaultMessage: 'Could not find document', + }) + ); + } +}; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts index 6c61e62ce0c66..c0dcc2dbdb0a9 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts @@ -16,6 +16,7 @@ import { addConnector } from '../../lib/connectors/add_connector'; import { fetchSyncJobsByConnectorId } from '../../lib/connectors/fetch_sync_jobs'; import { startConnectorSync } from '../../lib/connectors/start_sync'; import { updateConnectorConfiguration } from '../../lib/connectors/update_connector_configuration'; +import { updateConnectorNameAndDescription } from '../../lib/connectors/update_connector_name_and_description'; import { updateConnectorScheduling } from '../../lib/connectors/update_connector_scheduling'; import { updateConnectorServiceType } from '../../lib/connectors/update_connector_service_type'; import { updateConnectorStatus } from '../../lib/connectors/update_connector_status'; @@ -244,4 +245,28 @@ export function registerConnectorRoutes({ router, log }: RouteDependencies) { return response.ok({ body: result }); }) ); + + router.put( + { + path: '/internal/enterprise_search/connectors/{connectorId}/name_and_description', + validate: { + params: schema.object({ + connectorId: schema.string(), + }), + body: schema.object({ + name: schema.maybe(schema.string()), + description: schema.maybe(schema.string()), + }), + }, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + const { name, description } = request.body; + const result = await updateConnectorNameAndDescription(client, request.params.connectorId, { + description, + name, + }); + return response.ok({ body: result }); + }) + ); } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index deae7624de2d7..d069b09dd3c65 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -11006,7 +11006,6 @@ "xpack.enterpriseSearch.appSearch.tokens.search.name": "Clé de recherche publique", "xpack.enterpriseSearch.appSearch.tokens.update": "La clé d'API \"{name}\" a été mise à jour", "xpack.enterpriseSearch.automaticCrawlSchedule.title": "Planification automatisée de l’indexation", - "xpack.enterpriseSearch.connector.connectorNamePanel.title": "Nom", "xpack.enterpriseSearch.connector.connectorTypePanel.title": "Type de connecteur", "xpack.enterpriseSearch.connector.connectorTypePanel.unknown.label": "Inconnu", "xpack.enterpriseSearch.connector.ingestionStatus.title": "Statut de l'ingestion", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 0b2f36a944f93..a6f22902ac9ed 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10992,7 +10992,6 @@ "xpack.enterpriseSearch.appSearch.tokens.search.name": "公開検索キー", "xpack.enterpriseSearch.appSearch.tokens.update": "APIキー'{name}'が更新されました", "xpack.enterpriseSearch.automaticCrawlSchedule.title": "自動クローリングスケジュール", - "xpack.enterpriseSearch.connector.connectorNamePanel.title": "名前", "xpack.enterpriseSearch.connector.connectorTypePanel.title": "コネクタータイプ", "xpack.enterpriseSearch.connector.connectorTypePanel.unknown.label": "不明", "xpack.enterpriseSearch.connector.ingestionStatus.title": "インジェスチョンステータス", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 72d834b4b2dd6..315476cde96fa 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -11008,7 +11008,6 @@ "xpack.enterpriseSearch.appSearch.tokens.search.name": "公有搜索密钥", "xpack.enterpriseSearch.appSearch.tokens.update": "API 密钥“{name}”已更新", "xpack.enterpriseSearch.automaticCrawlSchedule.title": "自动化爬网计划", - "xpack.enterpriseSearch.connector.connectorNamePanel.title": "名称", "xpack.enterpriseSearch.connector.connectorTypePanel.title": "连接器类型", "xpack.enterpriseSearch.connector.connectorTypePanel.unknown.label": "未知", "xpack.enterpriseSearch.connector.ingestionStatus.title": "采集状态", From 841b9300a72900bf618f897a8f3e4a805d0e047d Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 20 Sep 2022 22:46:38 +0200 Subject: [PATCH 10/55] [ML] Explain Log Rate Spikes: Add link to Discover to grouped results table. (#141071) Adds link to Discover to grouped results table. --- .../spike_analysis_table.tsx | 7 + .../spike_analysis_table_groups.tsx | 161 ++++++++++++++++-- 2 files changed, 157 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx index 5a541c9e56af2..35f3ba368be9a 100644 --- a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx +++ b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx @@ -134,6 +134,7 @@ export const SpikeAnalysisTable: FC = ({ defaultMessage: 'Field name', }), sortable: true, + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisTableColumnFieldValue', @@ -143,6 +144,7 @@ export const SpikeAnalysisTable: FC = ({ }), render: (_, { fieldValue }) => String(fieldValue).slice(0, 50), sortable: true, + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisTableColumnLogRate', @@ -176,6 +178,7 @@ export const SpikeAnalysisTable: FC = ({ /> ), sortable: false, + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisTableColumnDocCount', @@ -185,6 +188,7 @@ export const SpikeAnalysisTable: FC = ({ defaultMessage: 'Doc count', }), sortable: true, + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisTableColumnPValue', @@ -212,6 +216,7 @@ export const SpikeAnalysisTable: FC = ({ ), render: (pValue: number | null) => pValue?.toPrecision(3) ?? NOT_AVAILABLE, sortable: true, + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisTableColumnImpact', @@ -242,6 +247,7 @@ export const SpikeAnalysisTable: FC = ({ return label ? {label.impact} : null; }, sortable: true, + valign: 'top', }, { 'data-test-subj': 'aiOpsSpikeAnalysisTableColumnAction', @@ -267,6 +273,7 @@ export const SpikeAnalysisTable: FC = ({ }, ], width: ACTIONS_COLUMN_WIDTH, + valign: 'top', }, ]; diff --git a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx index 37563fd2d43a0..c8f8410a56448 100644 --- a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx +++ b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx @@ -22,29 +22,40 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { escapeKuery } from '@kbn/es-query'; import { FormattedMessage } from '@kbn/i18n-react'; import type { ChangePoint } from '@kbn/ml-agg-utils'; +import { SEARCH_QUERY_LANGUAGE } from '../../application/utils/search_utils'; import { useEuiTheme } from '../../hooks/use_eui_theme'; +import { useAiopsAppContext } from '../../hooks/use_aiops_app_context'; import { MiniHistogram } from '../mini_histogram'; +import { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transactions_correlation_impact_label'; import { SpikeAnalysisTable } from './spike_analysis_table'; const NARROW_COLUMN_WIDTH = '120px'; const EXPAND_COLUMN_WIDTH = '40px'; +const ACTIONS_COLUMN_WIDTH = '60px'; const NOT_AVAILABLE = '--'; const PAGINATION_SIZE_OPTIONS = [5, 10, 20, 50]; const DEFAULT_SORT_FIELD = 'pValue'; const DEFAULT_SORT_DIRECTION = 'asc'; +const viewInDiscoverMessage = i18n.translate( + 'xpack.aiops.spikeAnalysisTable.linksMenu.viewInDiscover', + { + defaultMessage: 'View in Discover', + } +); interface GroupTableItem { id: string; docCount: number; pValue: number | null; - group: Record; - repeatedValues: Record; + group: Record; + repeatedValues: Record; histogram: ChangePoint['histogram']; } @@ -118,6 +129,71 @@ export const SpikeAnalysisGroupsTable: FC = ({ setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues); }; + const { application, share, data } = useAiopsAppContext(); + + const discoverLocator = useMemo( + () => share.url.locators.get('DISCOVER_APP_LOCATOR'), + [share.url.locators] + ); + + const discoverUrlError = useMemo(() => { + if (!application.capabilities.discover?.show) { + const discoverNotEnabled = i18n.translate( + 'xpack.aiops.spikeAnalysisTable.discoverNotEnabledErrorMessage', + { + defaultMessage: 'Discover is not enabled', + } + ); + + return discoverNotEnabled; + } + if (!discoverLocator) { + const discoverLocatorMissing = i18n.translate( + 'xpack.aiops.spikeAnalysisTable.discoverLocatorMissingErrorMessage', + { + defaultMessage: 'No locator for Discover detected', + } + ); + + return discoverLocatorMissing; + } + if (!dataViewId) { + const autoGeneratedDiscoverLinkError = i18n.translate( + 'xpack.aiops.spikeAnalysisTable.autoGeneratedDiscoverLinkErrorMessage', + { + defaultMessage: 'Unable to link to Discover; no data view exists for this index', + } + ); + + return autoGeneratedDiscoverLinkError; + } + }, [application.capabilities.discover?.show, dataViewId, discoverLocator]); + + const generateDiscoverUrl = async (groupTableItem: GroupTableItem) => { + if (discoverLocator !== undefined) { + const url = await discoverLocator.getRedirectUrl({ + indexPatternId: dataViewId, + timeRange: data.query.timefilter.timefilter.getTime(), + filters: data.query.filterManager.getFilters(), + query: { + language: SEARCH_QUERY_LANGUAGE.KUERY, + query: [ + ...Object.entries(groupTableItem.group).map( + ([fieldName, fieldValue]) => + `${escapeKuery(fieldName)}:${escapeKuery(String(fieldValue))}` + ), + ...Object.entries(groupTableItem.repeatedValues).map( + ([fieldName, fieldValue]) => + `${escapeKuery(fieldName)}:${escapeKuery(String(fieldValue))}` + ), + ].join(' AND '), + }, + }); + + return url; + } + }; + const columns: Array> = [ { align: RIGHT_ALIGNMENT, @@ -150,6 +226,7 @@ export const SpikeAnalysisGroupsTable: FC = ({ iconType={itemIdToExpandedRowMap[item.id] ? 'arrowUp' : 'arrowDown'} /> ), + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnGroup', @@ -200,6 +277,7 @@ export const SpikeAnalysisGroupsTable: FC = ({ }, sortable: false, textOnly: true, + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnLogRate', @@ -229,11 +307,26 @@ export const SpikeAnalysisGroupsTable: FC = ({ ), sortable: false, }, + { + 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnDocCount', + width: NARROW_COLUMN_WIDTH, + field: 'docCount', + name: i18n.translate('xpack.aiops.correlations.spikeAnalysisTableGroups.docCountLabel', { + defaultMessage: 'Doc count', + }), + sortable: true, + valign: 'top', + }, { 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnPValue', width: NARROW_COLUMN_WIDTH, @@ -260,18 +353,64 @@ export const SpikeAnalysisGroupsTable: FC = ({ ), render: (pValue: number | null) => pValue?.toPrecision(3) ?? NOT_AVAILABLE, sortable: true, + valign: 'top', }, { - 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnDocCount', - field: 'docCount', - name: i18n.translate( - 'xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.docCountLabel', - { - defaultMessage: 'Doc count', - } + 'data-test-subj': 'aiopsSpikeAnalysisTableColumnImpact', + width: NARROW_COLUMN_WIDTH, + field: 'pValue', + name: ( + + <> + + + + ), + render: (_, { pValue }) => { + if (!pValue) return NOT_AVAILABLE; + const label = getFailedTransactionsCorrelationImpactLabel(pValue); + return label ? {label.impact} : null; + }, sortable: true, - width: '20%', + valign: 'top', + }, + { + 'data-test-subj': 'aiOpsSpikeAnalysisTableColumnAction', + name: i18n.translate('xpack.aiops.spikeAnalysisTable.actionsColumnName', { + defaultMessage: 'Actions', + }), + actions: [ + { + name: () => ( + + + + ), + description: viewInDiscoverMessage, + type: 'button', + onClick: async (tableItem) => { + const openInDiscoverUrl = await generateDiscoverUrl(tableItem); + if (typeof openInDiscoverUrl === 'string') { + await application.navigateToUrl(openInDiscoverUrl); + } + }, + enabled: () => discoverUrlError === undefined, + }, + ], + width: ACTIONS_COLUMN_WIDTH, + valign: 'top', }, ]; From 2d0d3a58f2762cf3d0ae0f8a399676c24255a724 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 20 Sep 2022 16:49:27 -0400 Subject: [PATCH 11/55] [cft] Soft fail on timeout (#141165) --- .buildkite/pipelines/artifacts.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pipelines/artifacts.yml b/.buildkite/pipelines/artifacts.yml index b6d3cc9fc9b14..8ca3a55dff2e6 100644 --- a/.buildkite/pipelines/artifacts.yml +++ b/.buildkite/pipelines/artifacts.yml @@ -75,6 +75,7 @@ steps: label: 'Cloud Deployment' soft_fail: - exit_status: 255 + - exit_status: '-1' agents: queue: n2-2 timeout_in_minutes: 30 From e2ee8558a0bb9a9619018f07cbe0a3b3740190d5 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 20 Sep 2022 15:54:35 -0500 Subject: [PATCH 12/55] skip flaky suite. #141160 --- .../edit_policy/form_validation/downsample_interval.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts index 8ad72ca3d0a82..79f5fdc6e2840 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts @@ -12,7 +12,8 @@ import { PhaseWithDownsample } from '../../../../common/types'; import { setupEnvironment } from '../../helpers'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -describe(' downsample interval validation', () => { +// FLAKY: https://github.com/elastic/kibana/issues/141160 +describe.skip(' downsample interval validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); From 77ea0c14cf11ce6e8572c96e458e437e4d3e894f Mon Sep 17 00:00:00 2001 From: Adam Demjen Date: Tue, 20 Sep 2022 16:59:18 -0400 Subject: [PATCH 13/55] [8.5][ML Inference] Convert spaces to underscores in ML pipeline name (#141122) * Convert spaces to underscores in ML pipeline name --- .../create_ml_inference_pipeline.test.ts | 39 +++++++++++++------ .../utils/ml_inference_pipeline_utils.ts | 10 ++++- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/enterprise_search/server/utils/create_ml_inference_pipeline.test.ts b/x-pack/plugins/enterprise_search/server/utils/create_ml_inference_pipeline.test.ts index e5ab370216707..c34bbae2f97f1 100644 --- a/x-pack/plugins/enterprise_search/server/utils/create_ml_inference_pipeline.test.ts +++ b/x-pack/plugins/enterprise_search/server/utils/create_ml_inference_pipeline.test.ts @@ -33,6 +33,18 @@ describe('createMlInferencePipeline util function', () => { }, }; + mockClient.ml.getTrainedModels.mockImplementation(() => + Promise.resolve({ + trained_model_configs: [ + { + input: { + field_names: ['target-field'], + }, + }, + ], + }) + ); + beforeEach(() => { jest.clearAllMocks(); }); @@ -40,17 +52,6 @@ describe('createMlInferencePipeline util function', () => { it("should create the pipeline if it doesn't exist", async () => { mockClient.ingest.getPipeline.mockImplementation(() => Promise.reject({ statusCode: 404 })); // Pipeline does not exist mockClient.ingest.putPipeline.mockImplementation(() => Promise.resolve({ acknowledged: true })); - mockClient.ml.getTrainedModels.mockImplementation(() => - Promise.resolve({ - trained_model_configs: [ - { - input: { - field_names: ['target-field'], - }, - }, - ], - }) - ); const expectedResult = { created: true, @@ -69,6 +70,22 @@ describe('createMlInferencePipeline util function', () => { expect(mockClient.ingest.putPipeline).toHaveBeenCalled(); }); + it('should convert spaces to underscores in the pipeline name', async () => { + await createMlInferencePipeline( + 'my pipeline with spaces ', + modelId, + sourceField, + destinationField, + mockClient as unknown as ElasticsearchClient + ); + + expect(mockClient.ingest.putPipeline).toHaveBeenCalledWith( + expect.objectContaining({ + id: 'ml-inference-my_pipeline_with_spaces', + }) + ); + }); + it('should throw an error without creating the pipeline if it already exists', () => { mockClient.ingest.getPipeline.mockImplementation(() => Promise.resolve({ diff --git a/x-pack/plugins/enterprise_search/server/utils/ml_inference_pipeline_utils.ts b/x-pack/plugins/enterprise_search/server/utils/ml_inference_pipeline_utils.ts index ebced2c60280c..e059f5b9090c0 100644 --- a/x-pack/plugins/enterprise_search/server/utils/ml_inference_pipeline_utils.ts +++ b/x-pack/plugins/enterprise_search/server/utils/ml_inference_pipeline_utils.ts @@ -9,4 +9,12 @@ export const getInferencePipelineNameFromIndexName = (indexName: string) => `${indexName}@ml-inference`; export const getPrefixedInferencePipelineProcessorName = (pipelineName: string) => - pipelineName.startsWith('ml-inference-') ? pipelineName : `ml-inference-${pipelineName}`; + pipelineName.startsWith('ml-inference-') + ? formatPipelineName(pipelineName) + : `ml-inference-${formatPipelineName(pipelineName)}`; + +const formatPipelineName = (rawName: string) => + rawName + .trim() + .replace(/\s+/g, '_') // Convert whitespaces to underscores + .toLowerCase(); From 7cc3e68e109a61b8a0c251fcf839ca1690a4383d Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Tue, 20 Sep 2022 14:02:07 -0700 Subject: [PATCH 14/55] Revert "[cft] Soft fail on timeout (#141165)" This reverts commit 2d0d3a58f2762cf3d0ae0f8a399676c24255a724. --- .buildkite/pipelines/artifacts.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.buildkite/pipelines/artifacts.yml b/.buildkite/pipelines/artifacts.yml index 8ca3a55dff2e6..b6d3cc9fc9b14 100644 --- a/.buildkite/pipelines/artifacts.yml +++ b/.buildkite/pipelines/artifacts.yml @@ -75,7 +75,6 @@ steps: label: 'Cloud Deployment' soft_fail: - exit_status: 255 - - exit_status: '-1' agents: queue: n2-2 timeout_in_minutes: 30 From 923fb7242f78e37e5c26cf5bc22385fd346f7aff Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Tue, 20 Sep 2022 17:08:42 -0400 Subject: [PATCH 15/55] [Fleet] Show a warning in assets tab for permission errors (#141153) --- .../epm/screens/detail/assets/assets.tsx | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx index c65749178ddee..8d130c04bac5d 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/assets/assets.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useState } from 'react'; import { Redirect } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer, EuiCallOut } from '@elastic/eui'; import { groupBy } from 'lodash'; import type { ResolvedSimpleSavedObject } from '@kbn/core/public'; @@ -52,6 +52,7 @@ export const AssetsPage = ({ packageInfo }: AssetsPanelProps) => { const [assetSavedObjects, setAssetsSavedObjects] = useState(); const [fetchError, setFetchError] = useState(); const [isLoading, setIsLoading] = useState(true); + const [hasPermissionError, setHasPermissionError] = useState(false); useEffect(() => { const fetchAssetSavedObjects = async () => { @@ -94,6 +95,7 @@ export const AssetsPage = ({ packageInfo }: AssetsPanelProps) => { // Ignore privilege errors .catch((e: any) => { if (e?.body?.statusCode === 403) { + setHasPermissionError(true); return { resolved_objects: [] }; } else { throw e; @@ -161,6 +163,23 @@ export const AssetsPage = ({ packageInfo }: AssetsPanelProps) => { ); + } else if (hasPermissionError) { + content = ( + + } + > + + + ); } else if (assetSavedObjects === undefined || assetSavedObjects.length === 0) { if (customAssetsExtension) { // If a UI extension for custom asset entries is defined, render the custom component here despite From e82b7ff5826c204f6fd8df980d61b628a2dcd764 Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Wed, 21 Sep 2022 00:14:18 +0300 Subject: [PATCH 16/55] CSPM first usage collector (#140896) --- .../common/constants.ts | 1 + .../cloud_security_posture/kibana.json | 3 +- .../collectors/indices_stats_collector.ts | 84 +++++++++++++++++++ .../lib/telemetry/collectors/register.ts | 38 +++++++++ .../server/lib/telemetry/collectors/schema.ts | 56 +++++++++++++ .../server/lib/telemetry/collectors/types.ts | 23 +++++ .../cloud_security_posture/server/plugin.ts | 2 + .../cloud_security_posture/server/types.ts | 2 + .../schema/xpack_plugins.json | 56 +++++++++++++ 9 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/indices_stats_collector.ts create mode 100644 x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/register.ts create mode 100644 x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts create mode 100644 x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index df7c53e0bb320..240d14c4b573c 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -18,6 +18,7 @@ export const CSP_LATEST_FINDINGS_DATA_VIEW = 'logs-cloud_security_posture.findin export const FINDINGS_INDEX_NAME = 'logs-cloud_security_posture.findings'; export const FINDINGS_INDEX_PATTERN = 'logs-cloud_security_posture.findings-default*'; +export const FINDINGS_INDEX_DEFAULT_NS = 'logs-cloud_security_posture.findings-default'; export const LATEST_FINDINGS_INDEX_TEMPLATE_NAME = 'logs-cloud_security_posture.findings_latest'; export const LATEST_FINDINGS_INDEX_PATTERN = 'logs-cloud_security_posture.findings_latest-*'; diff --git a/x-pack/plugins/cloud_security_posture/kibana.json b/x-pack/plugins/cloud_security_posture/kibana.json index 059de58acc21e..4660b97445ce0 100755 --- a/x-pack/plugins/cloud_security_posture/kibana.json +++ b/x-pack/plugins/cloud_security_posture/kibana.json @@ -22,5 +22,6 @@ "cloud", "licensing" ], - "requiredBundles": ["kibanaReact"] + "requiredBundles": ["kibanaReact"], + "optionalPlugins": ["usageCollection"] } diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/indices_stats_collector.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/indices_stats_collector.ts new file mode 100644 index 0000000000000..a1bb49216262f --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/indices_stats_collector.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import type { Logger } from '@kbn/core/server'; +import { + BENCHMARK_SCORE_INDEX_DEFAULT_NS, + FINDINGS_INDEX_DEFAULT_NS, + LATEST_FINDINGS_INDEX_DEFAULT_NS, +} from '../../../../common/constants'; +import type { CspmIndicesStats, IndexStats } from './types'; + +export const getIndicesStats = async ( + esClient: ElasticsearchClient, + logger: Logger +): Promise => { + const [findings, latestFindings, score] = await Promise.all([ + getIndexStats(esClient, FINDINGS_INDEX_DEFAULT_NS, logger), + getIndexStats(esClient, LATEST_FINDINGS_INDEX_DEFAULT_NS, logger), + getIndexStats(esClient, BENCHMARK_SCORE_INDEX_DEFAULT_NS, logger), + ]); + return { + findings, + latest_findings: latestFindings, + score, + }; +}; + +const getIndexStats = async ( + esClient: ElasticsearchClient, + index: string, + logger: Logger +): Promise => { + try { + const isIndexExists = await esClient.indices.exists({ + index, + }); + + if (isIndexExists) { + const indexStats = await getIndexDocCount(esClient, index); + return { + doc_count: indexStats._all.primaries?.docs ? indexStats._all.primaries?.docs?.count : 0, + deleted: indexStats._all.primaries?.docs?.deleted + ? indexStats._all.primaries?.docs?.deleted + : 0, + size_in_bytes: indexStats._all.primaries?.store + ? indexStats._all.primaries?.store.size_in_bytes + : 0, + last_doc_timestamp: await getLatestDocTimestamp(esClient, index), + }; + } + + return {}; + } catch (e) { + logger.error(`Failed to get index stats for ${index}`); + return {}; + } +}; + +const getIndexDocCount = (esClient: ElasticsearchClient, index: string) => + esClient.indices.stats({ index }); + +const getLatestDocTimestamp = async ( + esClient: ElasticsearchClient, + index: string +): Promise => { + const latestTimestamp = await esClient.search({ + index, + query: { + match_all: {}, + }, + sort: '@timestamp:desc', + size: 1, + fields: ['@timestamp'], + _source: false, + }); + + const latestEventTimestamp = latestTimestamp.hits?.hits[0]?.fields; + + return latestEventTimestamp ? latestEventTimestamp['@timestamp'][0] : null; +}; diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/register.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/register.ts new file mode 100644 index 0000000000000..496890ca477d1 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/register.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 { CollectorFetchContext, UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; +import type { Logger } from '@kbn/core/server'; +import { getIndicesStats } from './indices_stats_collector'; +import { cspmUsageSchema } from './schema'; +import { CspmUsage } from './types'; + +export function registerCspmUsageCollector( + logger: Logger, + usageCollection?: UsageCollectionSetup +): void { + // usageCollection is an optional dependency, so make sure to return if it is not registered + if (!usageCollection) { + return; + } + + // Create usage collector + const cspmUsageCollector = usageCollection.makeUsageCollector({ + type: 'cloud_security_posture', + isReady: () => true, + fetch: async (collectorFetchContext: CollectorFetchContext) => { + const indicesStats = await getIndicesStats(collectorFetchContext.esClient, logger); + return { + indices: indicesStats, + }; + }, + schema: cspmUsageSchema, + }); + + // Register usage collector + usageCollection.registerCollector(cspmUsageCollector); +} diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts new file mode 100644 index 0000000000000..184963fc9a5d1 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { MakeSchemaFrom } from '@kbn/usage-collection-plugin/server'; +import type { CspmUsage } from './types'; + +export const cspmUsageSchema: MakeSchemaFrom = { + indices: { + findings: { + doc_count: { + type: 'long', + }, + deleted: { + type: 'long', + }, + size_in_bytes: { + type: 'long', + }, + last_doc_timestamp: { + type: 'date', + }, + }, + latest_findings: { + doc_count: { + type: 'long', + }, + deleted: { + type: 'long', + }, + size_in_bytes: { + type: 'long', + }, + last_doc_timestamp: { + type: 'date', + }, + }, + score: { + doc_count: { + type: 'long', + }, + deleted: { + type: 'long', + }, + size_in_bytes: { + type: 'long', + }, + last_doc_timestamp: { + type: 'date', + }, + }, + }, +}; diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts new file mode 100644 index 0000000000000..4cbb32578bf9a --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface CspmUsage { + indices: CspmIndicesStats; +} + +export interface CspmIndicesStats { + findings: IndexStats | {}; + latest_findings: IndexStats | {}; + score: IndexStats | {}; +} + +export interface IndexStats { + doc_count: number; + deleted: number; + size_in_bytes: number; + last_doc_timestamp: string | null; +} diff --git a/x-pack/plugins/cloud_security_posture/server/plugin.ts b/x-pack/plugins/cloud_security_posture/server/plugin.ts index 4603f42a0e09e..ba421346ae5db 100755 --- a/x-pack/plugins/cloud_security_posture/server/plugin.ts +++ b/x-pack/plugins/cloud_security_posture/server/plugin.ts @@ -52,6 +52,7 @@ import { scheduleFindingsStatsTask, setupFindingsStatsTask, } from './tasks/findings_stats_task'; +import { registerCspmUsageCollector } from './lib/telemetry/collectors/register'; export class CspPlugin implements @@ -82,6 +83,7 @@ export class CspPlugin const coreStartServices = core.getStartServices(); this.setupCspTasks(plugins.taskManager, coreStartServices, this.logger); + registerCspmUsageCollector(this.logger, plugins.usageCollection); this.isCloudEnabled = plugins.cloud.isCloudEnabled; diff --git a/x-pack/plugins/cloud_security_posture/server/types.ts b/x-pack/plugins/cloud_security_posture/server/types.ts index 115e353b50d51..ba69b8402bde0 100644 --- a/x-pack/plugins/cloud_security_posture/server/types.ts +++ b/x-pack/plugins/cloud_security_posture/server/types.ts @@ -31,6 +31,7 @@ import type { AgentPolicyServiceInterface, PackagePolicyClient, } from '@kbn/fleet-plugin/server'; +import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import type { FleetStartContract, FleetRequestHandlerContext } from '@kbn/fleet-plugin/server'; import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; @@ -46,6 +47,7 @@ export interface CspServerPluginSetupDeps { security: SecurityPluginSetup; cloud: CloudSetup; // optional + usageCollection?: UsageCollectionSetup; } export interface CspServerPluginStartDeps { diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index 266d8e3d20fe4..f5e06f58e8093 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -4917,6 +4917,62 @@ } } }, + "cloud_security_posture": { + "properties": { + "indices": { + "properties": { + "findings": { + "properties": { + "doc_count": { + "type": "long" + }, + "deleted": { + "type": "long" + }, + "size_in_bytes": { + "type": "long" + }, + "last_doc_timestamp": { + "type": "date" + } + } + }, + "latest_findings": { + "properties": { + "doc_count": { + "type": "long" + }, + "deleted": { + "type": "long" + }, + "size_in_bytes": { + "type": "long" + }, + "last_doc_timestamp": { + "type": "date" + } + } + }, + "score": { + "properties": { + "doc_count": { + "type": "long" + }, + "deleted": { + "type": "long" + }, + "size_in_bytes": { + "type": "long" + }, + "last_doc_timestamp": { + "type": "date" + } + } + } + } + } + } + }, "discoverEnhanced": { "properties": { "exploreDataInChartActionEnabled": { From fa636c655b25ccf7b8e4efa582affa3914097279 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Tue, 20 Sep 2022 17:19:21 -0400 Subject: [PATCH 17/55] [Synthetics] Project monitors - support lightweight project monitors (#141066) * Improve project formatter * update * update imports * adjust logic and add tests for lightweight project monitors * update test * update api test * test * update more test * more fix * update tests * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * remove references to preserve monitor id * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * adjust errors * adjust tests * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * update * code reuse * update type * add tests * update * update * fix types * deepclone policies * update test * add tests * update type * Update src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' Co-authored-by: shahzad31 Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../public/theme/kibana_theme_provider.tsx | 3 +- .../common/constants/monitor_defaults.ts | 3 +- .../common/formatters/browser/formatters.ts | 1 - .../common/formatters/common/formatters.ts | 1 + .../monitor_management/locations.ts | 6 +- .../monitor_management/monitor_types.ts | 11 +- .../monitor_types_project.ts | 16 +- .../synthetics_private_locations.ts | 13 +- .../monitor_add_edit/form/formatter.test.tsx | 2 + .../fleet_package/browser/normalizers.ts | 1 - .../fleet_package/common/normalizers.ts | 1 + .../monitor_cruds/add_monitor_project.ts | 7 +- .../monitor_cruds/monitor_validation.ts | 30 +- .../synthetics_service/formatters/browser.ts | 1 - .../synthetics_service/formatters/common.ts | 1 + .../normalizers/browser.test.ts | 267 --------- .../synthetics_service/normalizers/browser.ts | 157 ------ .../synthetics_private_location.ts | 3 +- .../normalizers/browser_monitor.test.ts | 286 ++++++++++ .../normalizers/browser_monitor.ts | 85 +++ .../normalizers/common_fields.ts | 184 +++++++ .../normalizers/http_monitor.ts | 55 ++ .../normalizers/icmp_monitor.ts | 58 ++ .../project_monitor/normalizers/index.ts | 63 +++ .../normalizers/tcp_monitor.ts | 56 ++ .../project_monitor_formatter.test.ts | 14 +- .../project_monitor_formatter.ts | 113 ++-- .../apis/uptime/rest/add_monitor.ts | 2 +- .../apis/uptime/rest/add_monitor_project.ts | 521 +++++++++++++++++- .../uptime/rest/fixtures/http_monitor.json | 3 +- .../uptime/rest/fixtures/icmp_monitor.json | 1 + .../fixtures/project_browser_monitor.json | 50 +- .../rest/fixtures/project_http_monitor.json | 76 +++ .../rest/fixtures/project_icmp_monitor.json | 47 ++ .../rest/fixtures/project_tcp_monitor.json | 43 ++ .../apis/uptime/rest/get_monitor.ts | 2 +- 36 files changed, 1632 insertions(+), 551 deletions(-) delete mode 100644 x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts delete mode 100644 x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.test.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/common_fields.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/http_monitor.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/icmp_monitor.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/index.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/tcp_monitor.ts rename x-pack/plugins/synthetics/server/synthetics_service/{ => project_monitor}/project_monitor_formatter.test.ts (97%) rename x-pack/plugins/synthetics/server/synthetics_service/{ => project_monitor}/project_monitor_formatter.ts (82%) create mode 100644 x-pack/test/api_integration/apis/uptime/rest/fixtures/project_http_monitor.json create mode 100644 x-pack/test/api_integration/apis/uptime/rest/fixtures/project_icmp_monitor.json create mode 100644 x-pack/test/api_integration/apis/uptime/rest/fixtures/project_tcp_monitor.json diff --git a/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx b/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx index 58bf763a60b16..29d2bd893a87d 100644 --- a/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx +++ b/src/plugins/interactive_setup/public/theme/kibana_theme_provider.tsx @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -import { EuiProvider, EuiProviderProps } from '@elastic/eui'; +import type { EuiProviderProps } from '@elastic/eui'; +import { EuiProvider } from '@elastic/eui'; import createCache from '@emotion/cache'; import type { FC } from 'react'; import React, { useMemo } from 'react'; diff --git a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts index 70b494a42f121..1d142bbe33c68 100644 --- a/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts +++ b/x-pack/plugins/synthetics/common/constants/monitor_defaults.ts @@ -46,6 +46,7 @@ export const DEFAULT_COMMON_FIELDS: CommonFields = { [ConfigKey.LOCATIONS]: [], [ConfigKey.NAMESPACE]: DEFAULT_NAMESPACE_STRING, [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.UI, + [ConfigKey.JOURNEY_ID]: '', }; export const DEFAULT_BROWSER_ADVANCED_FIELDS: BrowserAdvancedFields = { @@ -63,7 +64,6 @@ export const DEFAULT_BROWSER_ADVANCED_FIELDS: BrowserAdvancedFields = { export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { ...DEFAULT_COMMON_FIELDS, - [ConfigKey.JOURNEY_ID]: '', [ConfigKey.PROJECT_ID]: '', [ConfigKey.PLAYWRIGHT_OPTIONS]: '', [ConfigKey.METADATA]: { @@ -96,6 +96,7 @@ export const DEFAULT_BROWSER_SIMPLE_FIELDS: BrowserSimpleFields = { [ConfigKey.ZIP_URL_TLS_VERSION]: undefined, [ConfigKey.URLS]: '', [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, + [ConfigKey.TIMEOUT]: null, }; export const DEFAULT_HTTP_SIMPLE_FIELDS: HTTPSimpleFields = { diff --git a/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts b/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts index 1524e646bb508..f05003f650deb 100644 --- a/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts +++ b/x-pack/plugins/synthetics/common/formatters/browser/formatters.ts @@ -72,7 +72,6 @@ export const browserFormatters: BrowserFormatMap = { arrayToJsonFormatter(fields[ConfigKey.JOURNEY_FILTERS_TAGS]), [ConfigKey.THROTTLING_CONFIG]: throttlingFormatter, [ConfigKey.IGNORE_HTTPS_ERRORS]: null, - [ConfigKey.JOURNEY_ID]: null, [ConfigKey.PROJECT_ID]: null, [ConfigKey.PLAYWRIGHT_OPTIONS]: null, [ConfigKey.CUSTOM_HEARTBEAT_ID]: null, diff --git a/x-pack/plugins/synthetics/common/formatters/common/formatters.ts b/x-pack/plugins/synthetics/common/formatters/common/formatters.ts index 5a5fbb864ecb3..89bf8793302ba 100644 --- a/x-pack/plugins/synthetics/common/formatters/common/formatters.ts +++ b/x-pack/plugins/synthetics/common/formatters/common/formatters.ts @@ -28,6 +28,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.REVISION]: null, [ConfigKey.MONITOR_SOURCE_TYPE]: null, [ConfigKey.FORM_MONITOR_TYPE]: null, + [ConfigKey.JOURNEY_ID]: null, }; export const arrayToJsonFormatter = (value: string[] = []) => diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/locations.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/locations.ts index 9d5e28a29a6fc..9f27becbbb023 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/locations.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/locations.ts @@ -37,8 +37,8 @@ export const BandwidthLimitKeyCodec = tEnum( export type BandwidthLimitKeyType = t.TypeOf; export const LocationGeoCodec = t.interface({ - lat: t.number, - lon: t.number, + lat: t.union([t.string, t.number]), + lon: t.union([t.string, t.number]), }); export const LocationStatusCodec = tEnum('LocationStatus', LocationStatus); @@ -77,13 +77,13 @@ export const PublicLocationsCodec = t.array(PublicLocationCodec); export const MonitorServiceLocationCodec = t.intersection([ t.interface({ id: t.string, - isServiceManaged: t.boolean, }), t.partial({ label: t.string, geo: LocationGeoCodec, url: t.string, isInvalid: t.boolean, + isServiceManaged: t.boolean, }), ]); diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index ebb5376792d70..58e3a31df8a37 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -8,11 +8,7 @@ import * as t from 'io-ts'; import { secretKeys } from '../../constants/monitor_management'; import { ConfigKey } from './config_key'; -import { - MonitorServiceLocationsCodec, - MonitorServiceLocationCodec, - ServiceLocationErrors, -} from './locations'; +import { MonitorServiceLocationCodec, ServiceLocationErrors } from './locations'; import { DataStream, DataStreamCodec, @@ -25,6 +21,7 @@ import { VerificationModeCodec, } from './monitor_configs'; import { MetadataCodec } from './monitor_meta_data'; +import { PrivateLocationCodec } from './synthetics_private_locations'; const ScheduleCodec = t.interface({ number: t.string, @@ -77,7 +74,7 @@ export const CommonFieldsCodec = t.intersection([ [ConfigKey.SCHEDULE]: ScheduleCodec, [ConfigKey.APM_SERVICE_NAME]: t.string, [ConfigKey.TAGS]: t.array(t.string), - [ConfigKey.LOCATIONS]: MonitorServiceLocationsCodec, + [ConfigKey.LOCATIONS]: t.array(t.union([MonitorServiceLocationCodec, PrivateLocationCodec])), }), t.partial({ [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorTypeCodec, @@ -85,6 +82,7 @@ export const CommonFieldsCodec = t.intersection([ [ConfigKey.REVISION]: t.number, [ConfigKey.MONITOR_SOURCE_TYPE]: SourceTypeCodec, [ConfigKey.CONFIG_ID]: t.string, + [ConfigKey.JOURNEY_ID]: t.string, }), ]); @@ -218,7 +216,6 @@ export const EncryptedBrowserSimpleFieldsCodec = t.intersection([ }), t.partial({ [ConfigKey.PLAYWRIGHT_OPTIONS]: t.string, - [ConfigKey.JOURNEY_ID]: t.string, [ConfigKey.PROJECT_ID]: t.string, [ConfigKey.ORIGINAL_SPACE]: t.string, [ConfigKey.CUSTOM_HEARTBEAT_ID]: t.string, diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts index 072455c8914c7..6abcf4b832135 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts @@ -14,19 +14,21 @@ export const ProjectMonitorThrottlingConfigCodec = t.interface({ latency: t.number, }); -export const ProjectBrowserMonitorCodec = t.intersection([ +export const ProjectMonitorCodec = t.intersection([ t.interface({ + type: t.string, id: t.string, name: t.string, schedule: t.number, - content: t.string, locations: t.array(t.string), }), t.partial({ + content: t.string, + timeout: t.string, privateLocations: t.array(t.string), throttling: ProjectMonitorThrottlingConfigCodec, screenshot: ScreenshotOptionCodec, - tags: t.array(t.string), + tags: t.union([t.string, t.array(t.string)]), ignoreHTTPSErrors: t.boolean, apmServiceName: t.string, playwrightOptions: t.record(t.string, t.unknown), @@ -35,17 +37,21 @@ export const ProjectBrowserMonitorCodec = t.intersection([ }), params: t.record(t.string, t.unknown), enabled: t.boolean, + urls: t.union([t.string, t.array(t.string)]), + hosts: t.union([t.string, t.array(t.string)]), + max_redirects: t.string, + wait: t.string, }), ]); export const ProjectMonitorsRequestCodec = t.interface({ project: t.string, keep_stale: t.boolean, - monitors: t.array(ProjectBrowserMonitorCodec), + monitors: t.array(ProjectMonitorCodec), }); export type ProjectMonitorThrottlingConfig = t.TypeOf; -export type ProjectBrowserMonitor = t.TypeOf; +export type ProjectMonitor = t.TypeOf; export type ProjectMonitorsRequest = t.TypeOf; diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_private_locations.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_private_locations.ts index 69cd76d54db86..556f1e56ed102 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_private_locations.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_private_locations.ts @@ -7,18 +7,23 @@ import * as t from 'io-ts'; -export const PrivateLocationType = t.intersection([ +export const PrivateLocationCodec = t.intersection([ t.interface({ label: t.string, id: t.string, agentPolicyId: t.string, concurrentMonitors: t.number, }), - t.partial({ geo: t.interface({ lat: t.number, lon: t.number }) }), + t.partial({ + isServiceManaged: t.boolean, + /* Empty Lat lon was accidentally saved as an empty string instead of undefined or null + * Need a migration to fix */ + geo: t.interface({ lat: t.union([t.string, t.number]), lon: t.union([t.string, t.number]) }), + }), ]); export const SyntheticsPrivateLocationsType = t.type({ - locations: t.array(PrivateLocationType), + locations: t.array(PrivateLocationCodec), }); -export type PrivateLocation = t.TypeOf; +export type PrivateLocation = t.TypeOf; export type SyntheticsPrivateLocations = t.TypeOf; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.test.tsx index 1cf2baf1df94f..4b4e778b87b9b 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.test.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/formatter.test.tsx @@ -104,6 +104,7 @@ describe('format', () => { 'check.response.status': [], enabled, form_monitor_type: 'http', + journey_id: '', locations: [ { id: 'us_central', @@ -316,6 +317,7 @@ describe('format', () => { 'check.response.status': [], enabled: true, form_monitor_type: 'http', + journey_id: '', locations: [ { id: 'us_central', diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts index 0746f2cdae279..a8b59b16a3460 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts @@ -107,7 +107,6 @@ export const browserNormalizers: BrowserNormalizerMap = { ConfigKey.JOURNEY_FILTERS_TAGS ), [ConfigKey.IGNORE_HTTPS_ERRORS]: getBrowserNormalizer(ConfigKey.IGNORE_HTTPS_ERRORS), - [ConfigKey.JOURNEY_ID]: getBrowserNormalizer(ConfigKey.JOURNEY_ID), [ConfigKey.PROJECT_ID]: getBrowserNormalizer(ConfigKey.PROJECT_ID), [ConfigKey.PLAYWRIGHT_OPTIONS]: getBrowserNormalizer(ConfigKey.PLAYWRIGHT_OPTIONS), [ConfigKey.CUSTOM_HEARTBEAT_ID]: getBrowserNormalizer(ConfigKey.CUSTOM_HEARTBEAT_ID), diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts index bdea46781dfd9..14fab3caeb132 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/common/normalizers.ts @@ -92,4 +92,5 @@ export const commonNormalizers: CommonNormalizerMap = { [ConfigKey.REVISION]: getCommonNormalizer(ConfigKey.REVISION), [ConfigKey.MONITOR_SOURCE_TYPE]: getCommonNormalizer(ConfigKey.MONITOR_SOURCE_TYPE), [ConfigKey.FORM_MONITOR_TYPE]: getCommonNormalizer(ConfigKey.FORM_MONITOR_TYPE), + [ConfigKey.JOURNEY_ID]: getCommonNormalizer(ConfigKey.JOURNEY_ID), }; diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts index 8b81e34840c66..668d97a0819e3 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts @@ -6,11 +6,12 @@ */ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../legacy_uptime/lib/lib'; -import { ProjectBrowserMonitor } from '../../../common/runtime_types'; +import { ProjectMonitor } from '../../../common/runtime_types'; + import { SyntheticsStreamingRouteFactory } from '../../legacy_uptime/routes/types'; import { API_URLS } from '../../../common/constants'; import { getAllLocations } from '../../synthetics_service/get_all_locations'; -import { ProjectMonitorFormatter } from '../../synthetics_service/project_monitor_formatter'; +import { ProjectMonitorFormatter } from '../../synthetics_service/project_monitor/project_monitor_formatter'; export const addSyntheticsProjectMonitorRoute: SyntheticsStreamingRouteFactory = ( libs: UMServerLibs @@ -32,7 +33,7 @@ export const addSyntheticsProjectMonitorRoute: SyntheticsStreamingRouteFactory = subject, }): Promise => { try { - const monitors = (request.body?.monitors as ProjectBrowserMonitor[]) || []; + const monitors = (request.body?.monitors as ProjectMonitor[]) || []; const spaceId = server.spaces.spacesService.getSpaceId(request); const { keep_stale: keepStale, project: projectId } = request.body || {}; const { publicLocations, privateLocations } = await getAllLocations( diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts index 88ae4690dd4bd..d648722e0d5cd 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/monitor_validation.ts @@ -10,8 +10,8 @@ import { formatErrors } from '@kbn/securitysolution-io-ts-utils'; import { BrowserFieldsCodec, - ProjectBrowserMonitorCodec, - ProjectBrowserMonitor, + ProjectMonitorCodec, + ProjectMonitor, ConfigKey, DataStream, DataStreamCodec, @@ -34,16 +34,18 @@ const monitorTypeToCodecMap: Record = { [DataStream.BROWSER]: BrowserFieldsCodec, }; -/** - * Validates monitor fields with respect to the relevant Codec identified by object's 'type' property. - * @param monitorFields {MonitorFields} The mixed type representing the possible monitor payload from UI. - */ -export function validateMonitor(monitorFields: MonitorFields): { +export interface ValidationResult { valid: boolean; reason: string; details: string; payload: object; -} { +} + +/** + * Validates monitor fields with respect to the relevant Codec identified by object's 'type' property. + * @param monitorFields {MonitorFields} The mixed type representing the possible monitor payload from UI. + */ +export function validateMonitor(monitorFields: MonitorFields): ValidationResult { const { [ConfigKey.MONITOR_TYPE]: monitorType } = monitorFields; const decodedType = DataStreamCodec.decode(monitorType); @@ -82,15 +84,7 @@ export function validateMonitor(monitorFields: MonitorFields): { return { valid: true, reason: '', details: '', payload: monitorFields }; } -export function validateProjectMonitor( - monitorFields: ProjectBrowserMonitor, - projectId: string -): { - valid: boolean; - reason: string; - details: string; - payload: object; -} { +export function validateProjectMonitor(monitorFields: ProjectMonitor): ValidationResult { const locationsError = monitorFields.locations && monitorFields.locations.length === 0 && @@ -98,7 +92,7 @@ export function validateProjectMonitor( ? 'Invalid value "[]" supplied to field "locations"' : ''; // Cast it to ICMPCodec to satisfy typing. During runtime, correct codec will be used to decode. - const decodedMonitor = ProjectBrowserMonitorCodec.decode(monitorFields); + const decodedMonitor = ProjectMonitorCodec.decode(monitorFields); if (isLeft(decodedMonitor)) { return { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts index 7e8c75a708430..9c9d24a3f58f4 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/browser.ts @@ -66,7 +66,6 @@ export const browserFormatters: BrowserFormatMap = { [ConfigKey.JOURNEY_FILTERS_TAGS]: (fields) => arrayFormatter(fields[ConfigKey.JOURNEY_FILTERS_TAGS]), [ConfigKey.IGNORE_HTTPS_ERRORS]: null, - [ConfigKey.JOURNEY_ID]: null, [ConfigKey.PROJECT_ID]: null, [ConfigKey.PLAYWRIGHT_OPTIONS]: (fields) => stringToObjectFormatter(fields[ConfigKey.PLAYWRIGHT_OPTIONS] || ''), diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts index 0163ee52981e5..16a0829cbb710 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts @@ -30,6 +30,7 @@ export const commonFormatters: CommonFormatMap = { [ConfigKey.MONITOR_SOURCE_TYPE]: (fields) => fields[ConfigKey.MONITOR_SOURCE_TYPE] || SourceType.UI, [ConfigKey.FORM_MONITOR_TYPE]: null, + [ConfigKey.JOURNEY_ID]: null, }; export const arrayFormatter = (value: string[] = []) => (value.length ? value : null); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts deleted file mode 100644 index 3362585a523c1..0000000000000 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.test.ts +++ /dev/null @@ -1,267 +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 { - DataStream, - ScreenshotOption, - Locations, - LocationStatus, - ProjectBrowserMonitor, - PrivateLocation, -} from '../../../common/runtime_types'; -import { DEFAULT_FIELDS } from '../../../common/constants/monitor_defaults'; -import { normalizeProjectMonitors } from './browser'; - -describe('browser normalizers', () => { - describe('normalize push monitors', () => { - const playwrightOptions = { - headless: true, - }; - const params = { - url: 'test-url', - }; - const projectId = 'test-project-id'; - const locations: Locations = [ - { - id: 'us_central', - label: 'Test Location', - geo: { lat: 33.333, lon: 73.333 }, - url: 'test-url', - isServiceManaged: true, - status: LocationStatus.GA, - }, - { - id: 'us_east', - label: 'Test Location', - geo: { lat: 33.333, lon: 73.333 }, - url: 'test-url', - isServiceManaged: true, - status: LocationStatus.GA, - }, - ]; - const privateLocations: PrivateLocation[] = [ - { - id: 'germany', - label: 'Germany', - concurrentMonitors: 1, - agentPolicyId: 'germany', - }, - ]; - const monitors: ProjectBrowserMonitor[] = [ - { - id: 'test-id-1', - screenshot: ScreenshotOption.OFF, - name: 'test-name-1', - content: 'test content 1', - schedule: 3, - throttling: { - latency: 20, - upload: 10, - download: 5, - }, - locations: ['us_central'], - tags: ['tag1', 'tag2'], - ignoreHTTPSErrors: true, - apmServiceName: 'cart-service', - }, - { - id: 'test-id-2', - screenshot: ScreenshotOption.ON, - name: 'test-name-2', - content: 'test content 2', - schedule: 10, - throttling: { - latency: 18, - upload: 15, - download: 10, - }, - params: {}, - playwrightOptions: {}, - locations: ['us_central', 'us_east'], - tags: ['tag3', 'tag4'], - ignoreHTTPSErrors: false, - apmServiceName: 'bean-service', - }, - { - id: 'test-id-3', - screenshot: ScreenshotOption.ON, - name: 'test-name-3', - content: 'test content 3', - schedule: 10, - throttling: { - latency: 18, - upload: 15, - download: 10, - }, - params, - playwrightOptions, - locations: ['us_central', 'us_east'], - privateLocations: ['Germany'], - tags: ['tag3', 'tag4'], - ignoreHTTPSErrors: false, - apmServiceName: 'bean-service', - }, - ]; - - it('properly normalizes browser monitor', () => { - const actual = normalizeProjectMonitors({ - locations, - privateLocations, - monitors, - projectId, - namespace: 'test-space', - }); - expect(actual).toEqual([ - { - ...DEFAULT_FIELDS[DataStream.BROWSER], - journey_id: 'test-id-1', - ignore_https_errors: true, - origin: 'project', - locations: [ - { - geo: { - lat: 33.333, - lon: 73.333, - }, - id: 'us_central', - isServiceManaged: true, - label: 'Test Location', - url: 'test-url', - status: 'ga', - }, - ], - name: 'test-name-1', - schedule: { - number: '3', - unit: 'm', - }, - screenshots: 'off', - 'service.name': 'cart-service', - 'source.project.content': 'test content 1', - tags: ['tag1', 'tag2'], - 'throttling.config': '5d/10u/20l', - 'throttling.download_speed': '5', - 'throttling.is_enabled': true, - 'throttling.latency': '20', - 'throttling.upload_speed': '10', - params: '', - type: 'browser', - project_id: projectId, - namespace: 'test_space', - original_space: 'test-space', - custom_heartbeat_id: 'test-id-1-test-project-id-test-space', - timeout: null, - }, - { - ...DEFAULT_FIELDS[DataStream.BROWSER], - journey_id: 'test-id-2', - ignore_https_errors: false, - origin: 'project', - locations: [ - { - geo: { - lat: 33.333, - lon: 73.333, - }, - id: 'us_central', - isServiceManaged: true, - label: 'Test Location', - url: 'test-url', - status: 'ga', - }, - { - geo: { - lat: 33.333, - lon: 73.333, - }, - id: 'us_east', - isServiceManaged: true, - label: 'Test Location', - url: 'test-url', - status: 'ga', - }, - ], - name: 'test-name-2', - params: '', - playwright_options: '', - schedule: { - number: '10', - unit: 'm', - }, - screenshots: 'on', - 'service.name': 'bean-service', - 'source.project.content': 'test content 2', - tags: ['tag3', 'tag4'], - 'throttling.config': '10d/15u/18l', - 'throttling.download_speed': '10', - 'throttling.is_enabled': true, - 'throttling.latency': '18', - 'throttling.upload_speed': '15', - type: 'browser', - project_id: projectId, - namespace: 'test_space', - original_space: 'test-space', - custom_heartbeat_id: 'test-id-2-test-project-id-test-space', - timeout: null, - }, - { - ...DEFAULT_FIELDS[DataStream.BROWSER], - journey_id: 'test-id-3', - ignore_https_errors: false, - origin: 'project', - locations: [ - { - geo: { - lat: 33.333, - lon: 73.333, - }, - id: 'us_central', - isServiceManaged: true, - label: 'Test Location', - url: 'test-url', - status: 'ga', - }, - { - geo: { - lat: 33.333, - lon: 73.333, - }, - id: 'us_east', - isServiceManaged: true, - label: 'Test Location', - url: 'test-url', - status: 'ga', - }, - privateLocations[0], - ], - name: 'test-name-3', - params: JSON.stringify(params), - playwright_options: JSON.stringify(playwrightOptions), - schedule: { - number: '10', - unit: 'm', - }, - screenshots: 'on', - 'service.name': 'bean-service', - 'source.project.content': 'test content 3', - tags: ['tag3', 'tag4'], - 'throttling.config': '10d/15u/18l', - 'throttling.download_speed': '10', - 'throttling.is_enabled': true, - 'throttling.latency': '18', - 'throttling.upload_speed': '15', - type: 'browser', - project_id: projectId, - namespace: 'test_space', - original_space: 'test-space', - custom_heartbeat_id: 'test-id-3-test-project-id-test-space', - timeout: null, - }, - ]); - }); - }); -}); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts deleted file mode 100644 index 3b5d684fe0f58..0000000000000 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ /dev/null @@ -1,157 +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 { PrivateLocation } from '../../../common/runtime_types'; -import { DEFAULT_FIELDS } from '../../../common/constants/monitor_defaults'; -import { formatKibanaNamespace } from '../../../common/formatters'; -import { - BrowserFields, - ConfigKey, - DataStream, - FormMonitorType, - Locations, - ProjectBrowserMonitor, - ScheduleUnit, - SourceType, -} from '../../../common/runtime_types/monitor_management'; - -/* Represents all of the push-monitor related fields that need to be - * normalized. Excludes fields that we do not support for push monitors - * This type ensures that contributors remember to add normalizers for push - * monitors where appropriate when new keys are added to browser montiors */ -type NormalizedPublicFields = Omit< - BrowserFields, - | ConfigKey.METADATA - | ConfigKey.SOURCE_INLINE - | ConfigKey.SOURCE_ZIP_URL - | ConfigKey.SOURCE_ZIP_USERNAME - | ConfigKey.SOURCE_ZIP_PASSWORD - | ConfigKey.SOURCE_ZIP_FOLDER - | ConfigKey.SOURCE_ZIP_PROXY_URL - | ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES - | ConfigKey.ZIP_URL_TLS_CERTIFICATE - | ConfigKey.ZIP_URL_TLS_KEY - | ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE - | ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE - | ConfigKey.ZIP_URL_TLS_VERSION - | ConfigKey.JOURNEY_FILTERS_TAGS - | ConfigKey.SYNTHETICS_ARGS - | ConfigKey.PORT - | ConfigKey.URLS ->; - -export const normalizeProjectMonitor = ({ - locations = [], - privateLocations = [], - monitor, - projectId, - namespace, -}: { - locations: Locations; - privateLocations: PrivateLocation[]; - monitor: ProjectBrowserMonitor; - projectId: string; - namespace: string; -}): BrowserFields => { - const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; - const normalizedFields: NormalizedPublicFields = { - [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, - [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, - [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.PROJECT, - [ConfigKey.NAME]: monitor.name || '', - [ConfigKey.SCHEDULE]: { - number: `${monitor.schedule}`, - unit: ScheduleUnit.MINUTES, - }, - [ConfigKey.PROJECT_ID]: projectId || defaultFields[ConfigKey.PROJECT_ID], - [ConfigKey.JOURNEY_ID]: monitor.id || defaultFields[ConfigKey.JOURNEY_ID], - [ConfigKey.SOURCE_PROJECT_CONTENT]: - monitor.content || defaultFields[ConfigKey.SOURCE_PROJECT_CONTENT], - [ConfigKey.LOCATIONS]: getMonitorLocations({ - monitor, - privateLocations, - publicLocations: locations, - }), - [ConfigKey.THROTTLING_CONFIG]: monitor.throttling - ? `${monitor.throttling.download}d/${monitor.throttling.upload}u/${monitor.throttling.latency}l` - : defaultFields[ConfigKey.THROTTLING_CONFIG], - [ConfigKey.DOWNLOAD_SPEED]: `${ - monitor.throttling?.download || defaultFields[ConfigKey.DOWNLOAD_SPEED] - }`, - [ConfigKey.UPLOAD_SPEED]: `${ - monitor.throttling?.upload || defaultFields[ConfigKey.UPLOAD_SPEED] - }`, - [ConfigKey.IS_THROTTLING_ENABLED]: - Boolean(monitor.throttling) || defaultFields[ConfigKey.IS_THROTTLING_ENABLED], - [ConfigKey.LATENCY]: `${monitor.throttling?.latency || defaultFields[ConfigKey.LATENCY]}`, - [ConfigKey.APM_SERVICE_NAME]: - monitor.apmServiceName || defaultFields[ConfigKey.APM_SERVICE_NAME], - [ConfigKey.IGNORE_HTTPS_ERRORS]: - monitor.ignoreHTTPSErrors || defaultFields[ConfigKey.IGNORE_HTTPS_ERRORS], - [ConfigKey.SCREENSHOTS]: monitor.screenshot || defaultFields[ConfigKey.SCREENSHOTS], - [ConfigKey.TAGS]: monitor.tags || defaultFields[ConfigKey.TAGS], - [ConfigKey.PLAYWRIGHT_OPTIONS]: Object.keys(monitor.playwrightOptions || {}).length - ? JSON.stringify(monitor.playwrightOptions) - : defaultFields[ConfigKey.PLAYWRIGHT_OPTIONS], - [ConfigKey.PARAMS]: Object.keys(monitor.params || {}).length - ? JSON.stringify(monitor.params) - : defaultFields[ConfigKey.PARAMS], - [ConfigKey.JOURNEY_FILTERS_MATCH]: - monitor.filter?.match || defaultFields[ConfigKey.JOURNEY_FILTERS_MATCH], - [ConfigKey.NAMESPACE]: formatKibanaNamespace(namespace) || defaultFields[ConfigKey.NAMESPACE], - [ConfigKey.ORIGINAL_SPACE]: namespace || defaultFields[ConfigKey.ORIGINAL_SPACE], - [ConfigKey.CUSTOM_HEARTBEAT_ID]: `${monitor.id}-${projectId}-${namespace}`, - [ConfigKey.TIMEOUT]: null, - [ConfigKey.ENABLED]: monitor.enabled ?? defaultFields[ConfigKey.ENABLED], - }; - return { - ...DEFAULT_FIELDS[DataStream.BROWSER], - ...normalizedFields, - }; -}; - -export const normalizeProjectMonitors = ({ - locations = [], - privateLocations = [], - monitors = [], - projectId, - namespace, -}: { - locations: Locations; - privateLocations: PrivateLocation[]; - monitors: ProjectBrowserMonitor[]; - projectId: string; - namespace: string; -}) => { - return monitors.map((monitor) => { - return normalizeProjectMonitor({ monitor, locations, privateLocations, projectId, namespace }); - }); -}; - -export const getMonitorLocations = ({ - privateLocations, - publicLocations, - monitor, -}: { - monitor: ProjectBrowserMonitor; - privateLocations: PrivateLocation[]; - publicLocations: Locations; -}) => { - const publicLocs = - monitor.locations?.map((id) => { - return publicLocations.find((location) => location.id === id); - }) || []; - const privateLocs = - monitor.privateLocations?.map((locationName) => { - return privateLocations.find( - (location) => location.label.toLowerCase() === locationName.toLowerCase() - ); - }) || []; - return [...publicLocs, ...privateLocs].filter( - (location) => location !== undefined - ) as BrowserFields[ConfigKey.LOCATIONS]; -}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts b/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts index 23e2c97f2fda1..c694f2aa7567e 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts @@ -7,6 +7,7 @@ import { KibanaRequest, SavedObjectsClientContract } from '@kbn/core/server'; import { NewPackagePolicy } from '@kbn/fleet-plugin/common'; import { NewPackagePolicyWithId } from '@kbn/fleet-plugin/server/services/package_policy'; +import { cloneDeep } from 'lodash'; import { formatSyntheticsPolicy } from '../../../common/formatters/format_synthetics_policy'; import { getSyntheticsPrivateLocations } from '../../legacy_uptime/lib/saved_objects/private_locations'; import { @@ -55,7 +56,7 @@ export class SyntheticsPrivateLocation { const { label: locName } = privateLocation; - const newPolicy = { ...newPolicyTemplate }; + const newPolicy = cloneDeep(newPolicyTemplate); try { newPolicy.is_managed = true; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.test.ts new file mode 100644 index 0000000000000..ed02f1037e32b --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.test.ts @@ -0,0 +1,286 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + DataStream, + ScreenshotOption, + Locations, + LocationStatus, + ProjectMonitor, + PrivateLocation, +} from '../../../../common/runtime_types'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; +import { normalizeProjectMonitors } from '.'; + +describe('browser normalizers', () => { + describe('normalize push monitors', () => { + const playwrightOptions = { + headless: true, + }; + const params = { + url: 'test-url', + }; + const projectId = 'test-project-id'; + const locations: Locations = [ + { + id: 'us_central', + label: 'Test Location', + geo: { lat: 33.333, lon: 73.333 }, + url: 'test-url', + isServiceManaged: true, + status: LocationStatus.GA, + }, + { + id: 'us_east', + label: 'Test Location', + geo: { lat: 33.333, lon: 73.333 }, + url: 'test-url', + isServiceManaged: true, + status: LocationStatus.GA, + }, + ]; + const privateLocations: PrivateLocation[] = [ + { + id: 'germany', + label: 'Germany', + isServiceManaged: false, + concurrentMonitors: 1, + agentPolicyId: 'germany', + }, + ]; + const monitors: ProjectMonitor[] = [ + { + id: 'test-id-1', + screenshot: ScreenshotOption.OFF, + name: 'test-name-1', + content: 'test content 1', + schedule: 3, + throttling: { + latency: 20, + upload: 10, + download: 5, + }, + locations: ['us_central'], + tags: ['tag1', 'tag2'], + ignoreHTTPSErrors: true, + apmServiceName: 'cart-service', + type: DataStream.BROWSER, + }, + { + id: 'test-id-2', + screenshot: ScreenshotOption.ON, + name: 'test-name-2', + content: 'test content 2', + schedule: 10, + throttling: { + latency: 18, + upload: 15, + download: 10, + }, + params: {}, + playwrightOptions: {}, + locations: ['us_central', 'us_east'], + tags: ['tag3', 'tag4'], + ignoreHTTPSErrors: false, + apmServiceName: 'bean-service', + type: DataStream.BROWSER, + }, + { + id: 'test-id-3', + screenshot: ScreenshotOption.ON, + name: 'test-name-3', + content: 'test content 3', + schedule: 10, + throttling: { + latency: 18, + upload: 15, + download: 10, + }, + params, + playwrightOptions, + locations: ['us_central', 'us_east'], + privateLocations: ['Germany'], + tags: ['tag3', 'tag4'], + ignoreHTTPSErrors: false, + apmServiceName: 'bean-service', + type: DataStream.BROWSER, + }, + ]; + + it('properly normalizes browser monitor', () => { + const actual = normalizeProjectMonitors({ + locations, + privateLocations, + monitors, + projectId, + namespace: 'test-space', + }); + expect(actual).toEqual([ + { + normalizedFields: { + ...DEFAULT_FIELDS[DataStream.BROWSER], + journey_id: 'test-id-1', + ignore_https_errors: true, + origin: 'project', + locations: [ + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_central', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + status: 'ga', + }, + ], + name: 'test-name-1', + schedule: { + number: '3', + unit: 'm', + }, + screenshots: 'off', + 'service.name': 'cart-service', + 'source.project.content': 'test content 1', + tags: ['tag1', 'tag2'], + 'throttling.config': '5d/10u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '10', + params: '', + type: 'browser', + project_id: projectId, + namespace: 'test_space', + original_space: 'test-space', + custom_heartbeat_id: 'test-id-1-test-project-id-test-space', + timeout: null, + }, + unsupportedKeys: [], + }, + { + normalizedFields: { + ...DEFAULT_FIELDS[DataStream.BROWSER], + journey_id: 'test-id-2', + ignore_https_errors: false, + origin: 'project', + locations: [ + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_central', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + status: 'ga', + }, + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_east', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + status: 'ga', + }, + ], + name: 'test-name-2', + params: '', + playwright_options: '', + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': 'bean-service', + 'source.project.content': 'test content 2', + tags: ['tag3', 'tag4'], + 'throttling.config': '10d/15u/18l', + 'throttling.download_speed': '10', + 'throttling.is_enabled': true, + 'throttling.latency': '18', + 'throttling.upload_speed': '15', + type: 'browser', + project_id: projectId, + namespace: 'test_space', + original_space: 'test-space', + custom_heartbeat_id: 'test-id-2-test-project-id-test-space', + timeout: null, + }, + unsupportedKeys: [], + }, + { + normalizedFields: { + ...DEFAULT_FIELDS[DataStream.BROWSER], + journey_id: 'test-id-3', + ignore_https_errors: false, + origin: 'project', + locations: [ + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_central', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + status: 'ga', + }, + { + geo: { + lat: 33.333, + lon: 73.333, + }, + id: 'us_east', + isServiceManaged: true, + label: 'Test Location', + url: 'test-url', + status: 'ga', + }, + { + id: 'germany', + isServiceManaged: false, + label: 'Germany', + agentPolicyId: 'germany', + concurrentMonitors: 1, + }, + ], + name: 'test-name-3', + params: JSON.stringify(params), + playwright_options: JSON.stringify(playwrightOptions), + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': 'bean-service', + 'source.project.content': 'test content 3', + tags: ['tag3', 'tag4'], + 'throttling.config': '10d/15u/18l', + 'throttling.download_speed': '10', + 'throttling.is_enabled': true, + 'throttling.latency': '18', + 'throttling.upload_speed': '15', + type: 'browser', + project_id: projectId, + namespace: 'test_space', + original_space: 'test-space', + custom_heartbeat_id: 'test-id-3-test-project-id-test-space', + timeout: null, + }, + unsupportedKeys: [], + }, + ]); + }); + }); +}); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.ts new file mode 100644 index 0000000000000..aae7031435c74 --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/browser_monitor.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + BrowserFields, + ConfigKey, + DataStream, + FormMonitorType, + Locations, + PrivateLocation, + ProjectMonitor, +} from '../../../../common/runtime_types'; +import { getNormalizeCommonFields, getValueInSeconds } from './common_fields'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; + +export interface NormalizedProjectProps { + locations: Locations; + privateLocations: PrivateLocation[]; + monitor: ProjectMonitor; + projectId: string; + namespace: string; +} + +export const getNormalizeBrowserFields = ({ + locations = [], + privateLocations = [], + monitor, + projectId, + namespace, +}: NormalizedProjectProps): { normalizedFields: BrowserFields; unsupportedKeys: string[] } => { + const defaultFields = DEFAULT_FIELDS[DataStream.BROWSER]; + + const commonFields = getNormalizeCommonFields({ + locations, + privateLocations, + monitor, + projectId, + namespace, + }); + + const normalizedFields = { + ...commonFields, + [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.MULTISTEP, + [ConfigKey.SOURCE_PROJECT_CONTENT]: + monitor.content || defaultFields[ConfigKey.SOURCE_PROJECT_CONTENT], + [ConfigKey.THROTTLING_CONFIG]: monitor.throttling + ? `${monitor.throttling.download}d/${monitor.throttling.upload}u/${monitor.throttling.latency}l` + : defaultFields[ConfigKey.THROTTLING_CONFIG], + [ConfigKey.DOWNLOAD_SPEED]: `${ + monitor.throttling?.download || defaultFields[ConfigKey.DOWNLOAD_SPEED] + }`, + [ConfigKey.UPLOAD_SPEED]: `${ + monitor.throttling?.upload || defaultFields[ConfigKey.UPLOAD_SPEED] + }`, + [ConfigKey.IS_THROTTLING_ENABLED]: + Boolean(monitor.throttling) || defaultFields[ConfigKey.IS_THROTTLING_ENABLED], + [ConfigKey.LATENCY]: `${monitor.throttling?.latency || defaultFields[ConfigKey.LATENCY]}`, + [ConfigKey.IGNORE_HTTPS_ERRORS]: + monitor.ignoreHTTPSErrors || defaultFields[ConfigKey.IGNORE_HTTPS_ERRORS], + [ConfigKey.SCREENSHOTS]: monitor.screenshot || defaultFields[ConfigKey.SCREENSHOTS], + [ConfigKey.PLAYWRIGHT_OPTIONS]: Object.keys(monitor.playwrightOptions || {}).length + ? JSON.stringify(monitor.playwrightOptions) + : defaultFields[ConfigKey.PLAYWRIGHT_OPTIONS], + [ConfigKey.PARAMS]: Object.keys(monitor.params || {}).length + ? JSON.stringify(monitor.params) + : defaultFields[ConfigKey.PARAMS], + [ConfigKey.JOURNEY_FILTERS_MATCH]: + monitor.filter?.match || defaultFields[ConfigKey.JOURNEY_FILTERS_MATCH], + [ConfigKey.TIMEOUT]: monitor.timeout + ? getValueInSeconds(monitor.timeout) + : defaultFields[ConfigKey.TIMEOUT], + }; + return { + normalizedFields: { + ...defaultFields, + ...normalizedFields, + }, + unsupportedKeys: [], + }; +}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/common_fields.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/common_fields.ts new file mode 100644 index 0000000000000..31aebd0e8586e --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/common_fields.ts @@ -0,0 +1,184 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { omit } from 'lodash'; +import { formatKibanaNamespace } from '../../../../common/formatters'; +import { + BrowserFields, + ConfigKey, + CommonFields, + DataStream, + PrivateLocation, + Locations, + ProjectMonitor, + ScheduleUnit, + SourceType, +} from '../../../../common/runtime_types'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; +import { DEFAULT_COMMON_FIELDS } from '../../../../common/constants/monitor_defaults'; +import { NormalizedProjectProps } from '.'; + +export const getNormalizeCommonFields = ({ + locations = [], + privateLocations = [], + monitor, + projectId, + namespace, +}: NormalizedProjectProps): CommonFields => { + const defaultFields = DEFAULT_COMMON_FIELDS; + + const normalizedFields = { + [ConfigKey.JOURNEY_ID]: monitor.id || defaultFields[ConfigKey.JOURNEY_ID], + [ConfigKey.MONITOR_SOURCE_TYPE]: SourceType.PROJECT, + [ConfigKey.NAME]: monitor.name || '', + [ConfigKey.SCHEDULE]: { + number: `${monitor.schedule}`, + unit: ScheduleUnit.MINUTES, + }, + [ConfigKey.PROJECT_ID]: projectId, + [ConfigKey.LOCATIONS]: getMonitorLocations({ + monitor, + privateLocations, + publicLocations: locations, + }), + [ConfigKey.APM_SERVICE_NAME]: + monitor.apmServiceName || defaultFields[ConfigKey.APM_SERVICE_NAME], + [ConfigKey.TAGS]: getOptionalListField(monitor.tags) || defaultFields[ConfigKey.TAGS], + [ConfigKey.NAMESPACE]: formatKibanaNamespace(namespace) || defaultFields[ConfigKey.NAMESPACE], + [ConfigKey.ORIGINAL_SPACE]: namespace || defaultFields[ConfigKey.NAMESPACE], + [ConfigKey.CUSTOM_HEARTBEAT_ID]: getCustomHeartbeatId(monitor, projectId, namespace), + [ConfigKey.ENABLED]: monitor.enabled ?? defaultFields[ConfigKey.ENABLED], + }; + return { + ...defaultFields, + ...normalizedFields, + }; +}; + +export const getCustomHeartbeatId = ( + monitor: NormalizedProjectProps['monitor'], + projectId: string, + namespace: string +) => { + return `${monitor.id}-${projectId}-${namespace}`; +}; + +export const getMonitorLocations = ({ + privateLocations, + publicLocations, + monitor, +}: { + monitor: ProjectMonitor; + privateLocations: PrivateLocation[]; + publicLocations: Locations; +}) => { + const publicLocs = + monitor.locations?.map((id) => { + return publicLocations.find((location) => location.id === id); + }) || []; + const privateLocs = + monitor.privateLocations?.map((locationName) => { + return privateLocations.find( + (location) => + location.label.toLowerCase() === locationName.toLowerCase() || + location.id.toLowerCase() === locationName.toLowerCase() + ); + }) || []; + + return [...publicLocs, ...privateLocs].filter( + (location) => location !== undefined + ) as BrowserFields[ConfigKey.LOCATIONS]; +}; + +export const getValueInSeconds = (value: string) => { + const keyMap = { + h: 60 * 60, + m: 60, + s: 1, + }; + const key = value.slice(-1) as 'h' | 'm' | 's'; + const time = parseInt(value.slice(0, -1), 10); + const valueInSeconds = time * (keyMap[key] || 1); + return typeof valueInSeconds === 'number' ? `${valueInSeconds}` : null; +}; + +/** + * Accounts for array values that are optionally defined as a comma seperated list + * + * @param {Array | string} [value] + * @returns {array} Returns an array + */ +export const getOptionalListField = (value?: string[] | string): string[] => { + if (Array.isArray(value)) { + return value; + } + return value ? value.split(',') : []; +}; + +/** + * Accounts for heartbeat fields that are optionally an array or single string + * + * @param {Array | string} [value] + * @returns {string} Returns first item when the value is an array, or the value itself + */ +export const getOptionalArrayField = (value: string[] | string = '') => { + const array = getOptionalListField(value); + return array[0]; +}; + +/** + * Flattens arbitrary yaml into a synthetics monitor compatible configuration + * + * @param {Object} [monitor] + * @returns {Object} Returns an object containing synthetics-compatible configuration keys + */ +const flattenAndFormatObject = (obj: Record, prefix = '', keys: string[]) => + Object.keys(obj).reduce>((acc, k) => { + const pre = prefix.length ? prefix + '.' : ''; + const key = pre + k; + + /* If the key is an array of numbers, convert to an array of strings */ + if (Array.isArray(obj[k])) { + acc[key] = (obj[k] as unknown[]).map((value) => + typeof value === 'number' ? String(value) : value + ); + return acc; + } + + /* if the key is a supported key stop flattening early */ + if (keys.includes(key)) { + acc[key] = obj[k]; + return acc; + } + + if (typeof obj[k] === 'object') { + Object.assign(acc, flattenAndFormatObject(obj[k] as Record, pre + k, keys)); + } else { + acc[key] = obj[k]; + } + return acc; + }, {}); + +export const normalizeYamlConfig = (monitor: NormalizedProjectProps['monitor']) => { + const defaultFields = DEFAULT_FIELDS[monitor.type as DataStream]; + const supportedKeys = Object.keys(defaultFields); + const flattenedConfig = flattenAndFormatObject(monitor, '', supportedKeys); + const { + locations: _locations, + privateLocations: _privateLocations, + content: _content, + id: _id, + ...yamlConfig + } = flattenedConfig; + const unsupportedKeys = Object.keys(yamlConfig).filter((key) => !supportedKeys.includes(key)); + const supportedYamlConfig = omit(yamlConfig, unsupportedKeys); + + return { + yamlConfig: supportedYamlConfig, + unsupportedKeys, + }; +}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/http_monitor.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/http_monitor.ts new file mode 100644 index 0000000000000..6f637d818667a --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/http_monitor.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { getNormalizeCommonFields } from './common_fields'; +import { NormalizedProjectProps } from './browser_monitor'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; +import { + ConfigKey, + DataStream, + FormMonitorType, + HTTPFields, +} from '../../../../common/runtime_types/monitor_management'; +import { normalizeYamlConfig, getValueInSeconds, getOptionalArrayField } from './common_fields'; + +export const getNormalizeHTTPFields = ({ + locations = [], + privateLocations = [], + monitor, + projectId, + namespace, +}: NormalizedProjectProps): { normalizedFields: HTTPFields; unsupportedKeys: string[] } => { + const defaultFields = DEFAULT_FIELDS[DataStream.HTTP]; + const { yamlConfig, unsupportedKeys } = normalizeYamlConfig(monitor); + + const commonFields = getNormalizeCommonFields({ + locations, + privateLocations, + monitor, + projectId, + namespace, + }); + + const normalizedFields = { + ...yamlConfig, + ...commonFields, + [ConfigKey.MONITOR_TYPE]: DataStream.HTTP, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.HTTP, + [ConfigKey.URLS]: getOptionalArrayField(monitor.urls) || defaultFields[ConfigKey.URLS], + [ConfigKey.MAX_REDIRECTS]: + monitor[ConfigKey.MAX_REDIRECTS] || defaultFields[ConfigKey.MAX_REDIRECTS], + [ConfigKey.TIMEOUT]: monitor.timeout + ? getValueInSeconds(monitor.timeout) + : defaultFields[ConfigKey.TIMEOUT], + }; + return { + normalizedFields: { + ...defaultFields, + ...normalizedFields, + }, + unsupportedKeys, + }; +}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/icmp_monitor.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/icmp_monitor.ts new file mode 100644 index 0000000000000..282475f94d7cd --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/icmp_monitor.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getNormalizeCommonFields } from './common_fields'; +import { NormalizedProjectProps } from './browser_monitor'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; +import { + ConfigKey, + DataStream, + FormMonitorType, + ICMPFields, +} from '../../../../common/runtime_types/monitor_management'; +import { normalizeYamlConfig, getValueInSeconds, getOptionalArrayField } from './common_fields'; + +export const getNormalizeICMPFields = ({ + locations = [], + privateLocations = [], + monitor, + projectId, + namespace, +}: NormalizedProjectProps): { normalizedFields: ICMPFields; unsupportedKeys: string[] } => { + const defaultFields = DEFAULT_FIELDS[DataStream.ICMP]; + const { yamlConfig, unsupportedKeys } = normalizeYamlConfig(monitor); + + const commonFields = getNormalizeCommonFields({ + locations, + privateLocations, + monitor, + projectId, + namespace, + }); + + const normalizedFields = { + ...yamlConfig, + ...commonFields, + [ConfigKey.MONITOR_TYPE]: DataStream.ICMP, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.ICMP, + [ConfigKey.HOSTS]: + getOptionalArrayField(monitor[ConfigKey.HOSTS]) || defaultFields[ConfigKey.HOSTS], + [ConfigKey.TIMEOUT]: monitor.timeout + ? getValueInSeconds(monitor.timeout) + : defaultFields[ConfigKey.TIMEOUT], + [ConfigKey.WAIT]: monitor.wait + ? getValueInSeconds(monitor.wait) || defaultFields[ConfigKey.WAIT] + : defaultFields[ConfigKey.WAIT], + }; + return { + normalizedFields: { + ...defaultFields, + ...normalizedFields, + }, + unsupportedKeys, + }; +}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/index.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/index.ts new file mode 100644 index 0000000000000..82b2acfacbf5b --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/index.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + DataStream, + PrivateLocation, + Locations, + ProjectMonitor, +} from '../../../../common/runtime_types'; +import { getNormalizeBrowserFields } from './browser_monitor'; +import { getNormalizeICMPFields } from './icmp_monitor'; +import { getNormalizeTCPFields } from './tcp_monitor'; +import { getNormalizeHTTPFields } from './http_monitor'; + +export interface NormalizedProjectProps { + locations: Locations; + privateLocations: PrivateLocation[]; + monitor: ProjectMonitor; + projectId: string; + namespace: string; +} + +export const normalizeProjectMonitor = (props: NormalizedProjectProps) => { + const { monitor } = props; + const type = monitor.type || DataStream.BROWSER; + + switch (type) { + case DataStream.BROWSER: + return getNormalizeBrowserFields(props); + + case DataStream.HTTP: + return getNormalizeHTTPFields(props); + + case DataStream.TCP: + return getNormalizeTCPFields(props); + + case DataStream.ICMP: + return getNormalizeICMPFields(props); + default: + throw new Error(`Unsupported monitor type ${monitor.type}`); + } +}; + +export const normalizeProjectMonitors = ({ + locations = [], + privateLocations = [], + monitors = [], + projectId, + namespace, +}: { + locations: Locations; + privateLocations: PrivateLocation[]; + monitors: ProjectMonitor[]; + projectId: string; + namespace: string; +}) => { + return monitors.map((monitor) => { + return normalizeProjectMonitor({ monitor, locations, privateLocations, projectId, namespace }); + }); +}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/tcp_monitor.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/tcp_monitor.ts new file mode 100644 index 0000000000000..8a85b2959d804 --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/normalizers/tcp_monitor.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { NormalizedProjectProps } from './browser_monitor'; +import { DEFAULT_FIELDS } from '../../../../common/constants/monitor_defaults'; +import { normalizeYamlConfig, getValueInSeconds } from './common_fields'; + +import { + ConfigKey, + DataStream, + FormMonitorType, + TCPFields, +} from '../../../../common/runtime_types/monitor_management'; +import { getNormalizeCommonFields, getOptionalArrayField } from './common_fields'; + +export const getNormalizeTCPFields = ({ + locations = [], + privateLocations = [], + monitor, + projectId, + namespace, +}: NormalizedProjectProps): { normalizedFields: TCPFields; unsupportedKeys: string[] } => { + const defaultFields = DEFAULT_FIELDS[DataStream.TCP]; + const { yamlConfig, unsupportedKeys } = normalizeYamlConfig(monitor); + + const commonFields = getNormalizeCommonFields({ + locations, + privateLocations, + monitor, + projectId, + namespace, + }); + + const normalizedFields = { + ...yamlConfig, + ...commonFields, + [ConfigKey.MONITOR_TYPE]: DataStream.TCP, + [ConfigKey.FORM_MONITOR_TYPE]: FormMonitorType.TCP, + [ConfigKey.HOSTS]: + getOptionalArrayField(monitor[ConfigKey.HOSTS]) || defaultFields[ConfigKey.HOSTS], + [ConfigKey.TIMEOUT]: monitor.timeout + ? getValueInSeconds(monitor.timeout) + : defaultFields[ConfigKey.TIMEOUT], + }; + return { + normalizedFields: { + ...defaultFields, + ...normalizedFields, + }, + unsupportedKeys, + }; +}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.test.ts similarity index 97% rename from x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.test.ts rename to x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.test.ts index e7175bec58057..a5fb9b774cf2c 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.test.ts @@ -10,20 +10,21 @@ import { INSUFFICIENT_FLEET_PERMISSIONS, ProjectMonitorFormatter, } from './project_monitor_formatter'; -import { LocationStatus } from '../../common/runtime_types'; +import { LocationStatus } from '../../../common/runtime_types'; import { times } from 'lodash'; -import { SyntheticsService } from './synthetics_service'; -import { UptimeServerSetup } from '../legacy_uptime/lib/adapters'; +import { SyntheticsService } from '../synthetics_service'; +import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; -import { SyntheticsMonitorClient } from './synthetics_monitor/synthetics_monitor_client'; +import { SyntheticsMonitorClient } from '../synthetics_monitor/synthetics_monitor_client'; import { httpServerMock } from '@kbn/core-http-server-mocks'; import { Subject } from 'rxjs'; -import { formatSecrets } from './utils'; +import { formatSecrets } from '../utils'; -import * as telemetryHooks from '../routes/telemetry/monitor_upgrade_sender'; +import * as telemetryHooks from '../../routes/telemetry/monitor_upgrade_sender'; const testMonitors = [ { + type: 'browser', throttling: { download: 5, upload: 3, latency: 20 }, schedule: 3, locations: [], @@ -46,6 +47,7 @@ const testMonitors = [ filter: { match: 'check if title is present 10 0' }, }, { + type: 'browser', throttling: { download: 5, upload: 3, latency: 20 }, schedule: 3, locations: [], diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts similarity index 82% rename from x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts rename to x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts index b859f37ed87fc..744003d16ea3f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor_formatter.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts @@ -13,30 +13,34 @@ import { SavedObjectsFindResult, } from '@kbn/core/server'; import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; -import { syncNewMonitorBulk } from '../routes/monitor_cruds/bulk_cruds/add_monitor_bulk'; -import { deleteMonitorBulk } from '../routes/monitor_cruds/bulk_cruds/delete_monitor_bulk'; -import { SyntheticsMonitorClient } from './synthetics_monitor/synthetics_monitor_client'; +import { syncNewMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/add_monitor_bulk'; +import { deleteMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/delete_monitor_bulk'; +import { SyntheticsMonitorClient } from '../synthetics_monitor/synthetics_monitor_client'; import { BrowserFields, ConfigKey, SyntheticsMonitorWithSecrets, EncryptedSyntheticsMonitor, ServiceLocationErrors, - ProjectBrowserMonitor, + ProjectMonitor, Locations, SyntheticsMonitor, MonitorFields, PrivateLocation, -} from '../../common/runtime_types'; +} from '../../../common/runtime_types'; import { syntheticsMonitorType, syntheticsMonitor, -} from '../legacy_uptime/lib/saved_objects/synthetics_monitor'; -import { normalizeProjectMonitor } from './normalizers/browser'; -import { formatSecrets, normalizeSecrets } from './utils/secrets'; -import { syncEditedMonitor } from '../routes/monitor_cruds/edit_monitor'; -import { validateProjectMonitor } from '../routes/monitor_cruds/monitor_validation'; -import type { UptimeServerSetup } from '../legacy_uptime/lib/adapters/framework'; +} from '../../legacy_uptime/lib/saved_objects/synthetics_monitor'; +import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; +import { formatSecrets, normalizeSecrets } from '../utils/secrets'; +import { syncEditedMonitor } from '../../routes/monitor_cruds/edit_monitor'; +import { + validateProjectMonitor, + validateMonitor, + ValidationResult, +} from '../../routes/monitor_cruds/monitor_validation'; +import { normalizeProjectMonitor } from './normalizers'; interface StaleMonitor { stale: boolean; @@ -44,7 +48,7 @@ interface StaleMonitor { savedObjectId: string; } type StaleMonitorMap = Record; -type FailedMonitors = Array<{ id?: string; reason: string; details: string; payload?: object }>; +type FailedError = Array<{ id?: string; reason: string; details: string; payload?: object }>; export const INSUFFICIENT_FLEET_PERMISSIONS = 'Insufficient permissions. In order to configure private locations, you must have Fleet and Integrations write permissions. To resolve, please generate a new API key with a user who has Fleet and Integrations write permissions.'; @@ -58,13 +62,13 @@ export class ProjectMonitorFormatter { private savedObjectsClient: SavedObjectsClientContract; private encryptedSavedObjectsClient: EncryptedSavedObjectsClient; private staleMonitorsMap: StaleMonitorMap = {}; - private monitors: ProjectBrowserMonitor[] = []; + private monitors: ProjectMonitor[] = []; public createdMonitors: string[] = []; public deletedMonitors: string[] = []; public updatedMonitors: string[] = []; public staleMonitors: string[] = []; - public failedMonitors: FailedMonitors = []; - public failedStaleMonitors: FailedMonitors = []; + public failedMonitors: FailedError = []; + public failedStaleMonitors: FailedError = []; private server: UptimeServerSetup; private projectFilter: string; private syntheticsMonitorClient: SyntheticsMonitorClient; @@ -94,7 +98,7 @@ export class ProjectMonitorFormatter { encryptedSavedObjectsClient: EncryptedSavedObjectsClient; projectId: string; spaceId: string; - monitors: ProjectBrowserMonitor[]; + monitors: ProjectMonitor[]; server: UptimeServerSetup; syntheticsMonitorClient: SyntheticsMonitorClient; request: KibanaRequest; @@ -138,9 +142,9 @@ export class ProjectMonitorFormatter { if (this.staleMonitorsMap[monitor.id]) { this.staleMonitorsMap[monitor.id].stale = false; } - normalizedUpdateMonitors.push(normM); + normalizedUpdateMonitors.push(normM as MonitorFields); } else { - normalizedNewMonitors.push(normM); + normalizedNewMonitors.push(normM as MonitorFields); } } } @@ -152,7 +156,7 @@ export class ProjectMonitorFormatter { await this.handleStaleMonitors(); }; - validatePermissions = async ({ monitor }: { monitor: ProjectBrowserMonitor }) => { + validatePermissions = async ({ monitor }: { monitor: ProjectMonitor }) => { if (this.writeIntegrationPoliciesPermissions || (monitor.privateLocations ?? []).length === 0) { return; } @@ -167,11 +171,11 @@ export class ProjectMonitorFormatter { } }; - validateProjectMonitor = async ({ monitor }: { monitor: ProjectBrowserMonitor }) => { + validateProjectMonitor = async ({ monitor }: { monitor: ProjectMonitor }) => { try { await this.validatePermissions({ monitor }); - const normalizedMonitor = normalizeProjectMonitor({ + const { normalizedFields: normalizedMonitor, unsupportedKeys } = normalizeProjectMonitor({ monitor, locations: this.locations, privateLocations: this.privateLocations, @@ -179,19 +183,40 @@ export class ProjectMonitorFormatter { namespace: this.spaceId, }); - const validationResult = validateProjectMonitor(monitor, this.projectId); - - if (!validationResult.valid) { - const { reason: message, details, payload } = validationResult; + if (unsupportedKeys.length) { this.failedMonitors.push({ id: monitor.id, - reason: message, - details, - payload, + reason: 'Unsupported Heartbeat option', + details: `The following Heartbeat options are not supported for ${ + monitor.type + } project monitors in ${this.server.kibanaVersion}: ${unsupportedKeys.join('|')}`, }); - if (this.staleMonitorsMap[monitor.id]) { - this.staleMonitorsMap[monitor.id].stale = false; - } + this.handleStreamingMessage({ + message: `${monitor.id}: failed to create or update monitor`, + }); + return null; + } + + /* Validates that the payload sent from the synthetics agent is valid */ + const { valid: isMonitorPayloadValid } = this.validateMonitor({ + validationResult: validateProjectMonitor({ + ...monitor, + type: normalizedMonitor[ConfigKey.MONITOR_TYPE], + }), + monitorId: monitor.id, + }); + + if (!isMonitorPayloadValid) { + return null; + } + + /* Validates that the normalized monitor is a valid monitor saved object type */ + const { valid: isNormalizedMonitorValid } = this.validateMonitor({ + validationResult: validateMonitor(normalizedMonitor as MonitorFields), + monitorId: monitor.id, + }); + + if (!isNormalizedMonitorValid) { return null; } @@ -310,7 +335,7 @@ export class ProjectMonitorFormatter { try { for (const monitor of monitors) { const previousMonitor = await this.getExistingMonitor(monitor[ConfigKey.JOURNEY_ID]!); - await this.updateMonitor(previousMonitor, monitor); + await this.updateMonitor(previousMonitor, monitor as MonitorFields); } if (monitors.length > 0) { @@ -335,7 +360,7 @@ export class ProjectMonitorFormatter { private updateMonitor = async ( previousMonitor: SavedObjectsFindResult, - normalizedMonitor: BrowserFields + normalizedMonitor: MonitorFields ): Promise<{ editedMonitor: SavedObjectsUpdateResponse; errors: ServiceLocationErrors; @@ -478,4 +503,26 @@ export class ProjectMonitorFormatter { this.subject?.next(message); } }; + + private validateMonitor = ({ + validationResult, + monitorId, + }: { + validationResult: ValidationResult; + monitorId: string; + }) => { + const { reason: message, details, payload: validationPayload, valid } = validationResult; + if (!valid) { + this.failedMonitors.push({ + id: monitorId, + reason: message, + details, + payload: validationPayload, + }); + if (this.staleMonitorsMap[monitorId]) { + this.staleMonitorsMap[monitorId].stale = false; + } + } + return validationResult; + }; } diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts index 833a5522ec37d..4e65bf1c4dbe3 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts @@ -21,7 +21,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { getFixtureJson } from './helper/get_fixture_json'; export default function ({ getService }: FtrProviderContext) { - describe('[POST] /internal/uptime/service/monitors', function () { + describe('AddNewMonitors', function () { this.tags('skipCloud'); const supertestAPI = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts index 9902a2aa98984..3c5442d6fdc90 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts @@ -31,6 +31,9 @@ export default function ({ getService }: FtrProviderContext) { const projectMonitorEndpoint = kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT; let projectMonitors: ProjectMonitorsRequest; + let httpProjectMonitors: ProjectMonitorsRequest; + let tcpProjectMonitors: ProjectMonitorsRequest; + let icmpProjectMonitors: ProjectMonitorsRequest; let testPolicyId = ''; const testPrivateLocations = new PrivateLocationTestService(getService); @@ -88,6 +91,272 @@ export default function ({ getService }: FtrProviderContext) { beforeEach(() => { projectMonitors = setUniqueIds(getFixtureJson('project_browser_monitor')); + httpProjectMonitors = setUniqueIds(getFixtureJson('project_http_monitor')); + tcpProjectMonitors = setUniqueIds(getFixtureJson('project_tcp_monitor')); + icmpProjectMonitors = setUniqueIds(getFixtureJson('project_icmp_monitor')); + }); + + it('project monitors - handles http monitors', async () => { + const kibanaVersion = await kibanaServer.version.get(); + const successfulMonitors = [httpProjectMonitors.monitors[1]]; + + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(httpProjectMonitors) + ); + + expect(messages).to.have.length(3); + expect(messages[2].updatedMonitors).eql([]); + expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); + expect(messages[2].failedMonitors).eql([ + { + id: httpProjectMonitors.monitors[0].id, + details: `The following Heartbeat options are not supported for ${httpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: check.response.body|unsupportedKey.nestedUnsupportedKey`, + reason: 'Unsupported Heartbeat option', + }, + ]); + + for (const monitor of successfulMonitors) { + const journeyId = monitor.id; + const createdMonitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId}` }) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(createdMonitorsResponse.body.monitors[0].attributes).to.eql({ + __ui: { + is_tls_enabled: false, + }, + 'check.request.method': 'POST', + 'check.response.status': ['200'], + config_id: '', + custom_heartbeat_id: `${journeyId}-test-suite-default`, + enabled: false, + form_monitor_type: 'http', + journey_id: journeyId, + locations: [ + { + geo: { + lat: 0, + lon: 0, + }, + id: 'localhost', + isInvalid: false, + isServiceManaged: true, + label: 'Local Synthetics Service', + status: 'experimental', + url: 'mockDevUrl', + }, + ], + max_redirects: '0', + name: monitor.name, + namespace: 'default', + origin: 'project', + original_space: 'default', + project_id: 'test-suite', + proxy_url: '', + 'response.include_body': 'always', + 'response.include_headers': false, + revision: 1, + schedule: { + number: '60', + unit: 'm', + }, + 'service.name': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + tags: Array.isArray(monitor.tags) ? monitor.tags : monitor.tags?.split(','), + timeout: '80', + type: 'http', + urls: Array.isArray(monitor.urls) ? monitor.urls?.[0] : monitor.urls, + }); + } + } finally { + await Promise.all([ + successfulMonitors.map((monitor) => { + return deleteMonitor(monitor.id, httpProjectMonitors.project); + }), + ]); + } + }); + + it('project monitors - handles tcp monitors', async () => { + const successfulMonitors = [tcpProjectMonitors.monitors[0], tcpProjectMonitors.monitors[1]]; + const kibanaVersion = await kibanaServer.version.get(); + + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(tcpProjectMonitors) + ); + + expect(messages).to.have.length(3); + expect(messages[2].updatedMonitors).eql([]); + expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); + expect(messages[2].failedMonitors).eql([ + { + id: tcpProjectMonitors.monitors[2].id, + details: `The following Heartbeat options are not supported for ${tcpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: ports|unsupportedKey.nestedUnsupportedKey`, + reason: 'Unsupported Heartbeat option', + }, + ]); + + for (const monitor of successfulMonitors) { + const journeyId = monitor.id; + const createdMonitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId}` }) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(createdMonitorsResponse.body.monitors[0].attributes).to.eql({ + __ui: { + is_tls_enabled: false, + }, + config_id: '', + custom_heartbeat_id: `${journeyId}-test-suite-default`, + enabled: true, + form_monitor_type: 'tcp', + journey_id: journeyId, + locations: [ + { + geo: { + lat: 0, + lon: 0, + }, + id: 'localhost', + isInvalid: false, + isServiceManaged: true, + label: 'Local Synthetics Service', + status: 'experimental', + url: 'mockDevUrl', + }, + ], + name: monitor.name, + namespace: 'default', + origin: 'project', + original_space: 'default', + project_id: 'test-suite', + revision: 1, + schedule: { + number: '1', + unit: 'm', + }, + proxy_url: '', + proxy_use_local_resolver: false, + 'service.name': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + tags: Array.isArray(monitor.tags) ? monitor.tags : monitor.tags?.split(','), + timeout: '16', + type: 'tcp', + hosts: Array.isArray(monitor.hosts) ? monitor.hosts?.[0] : monitor.hosts, + }); + } + } finally { + await Promise.all([ + successfulMonitors.map((monitor) => { + return deleteMonitor(monitor.id, tcpProjectMonitors.project); + }), + ]); + } + }); + + it('project monitors - handles icmp monitors', async () => { + const successfulMonitors = [icmpProjectMonitors.monitors[0], icmpProjectMonitors.monitors[1]]; + const kibanaVersion = await kibanaServer.version.get(); + + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(icmpProjectMonitors) + ); + + expect(messages).to.have.length(3); + expect(messages[2].updatedMonitors).eql([]); + expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); + expect(messages[2].failedMonitors).eql([ + { + id: icmpProjectMonitors.monitors[2].id, + details: `The following Heartbeat options are not supported for ${icmpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: unsupportedKey.nestedUnsupportedKey`, + reason: 'Unsupported Heartbeat option', + }, + ]); + + for (const monitor of successfulMonitors) { + const journeyId = monitor.id; + const createdMonitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId}` }) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(createdMonitorsResponse.body.monitors[0].attributes).to.eql({ + config_id: '', + custom_heartbeat_id: `${journeyId}-test-suite-default`, + enabled: true, + form_monitor_type: 'icmp', + journey_id: journeyId, + locations: [ + { + geo: { + lat: 0, + lon: 0, + }, + id: 'localhost', + isInvalid: false, + isServiceManaged: true, + label: 'Local Synthetics Service', + status: 'experimental', + url: 'mockDevUrl', + }, + { + agentPolicyId: testPolicyId, + concurrentMonitors: 1, + geo: { + lat: '', + lon: '', + }, + id: testPolicyId, + isInvalid: false, + isServiceManaged: false, + label: 'Test private location 0', + }, + ], + name: monitor.name, + namespace: 'default', + origin: 'project', + original_space: 'default', + project_id: 'test-suite', + revision: 1, + schedule: { + number: '1', + unit: 'm', + }, + 'service.name': '', + tags: Array.isArray(monitor.tags) ? monitor.tags : monitor.tags?.split(','), + timeout: '16', + type: 'icmp', + hosts: Array.isArray(monitor.hosts) ? monitor.hosts?.[0] : monitor.hosts, + wait: + monitor.wait?.slice(-1) === 's' + ? monitor.wait?.slice(0, -1) + : `${parseInt(monitor.wait?.slice(0, -1) || '1', 10) * 60}`, + }); + } + } finally { + await Promise.all([ + successfulMonitors.map((monitor) => { + return deleteMonitor(monitor.id, icmpProjectMonitors.project); + }), + ]); + } }); it('project monitors - returns a list of successfully created monitors', async () => { @@ -468,8 +737,7 @@ export default function ({ getService }: FtrProviderContext) { expect(messages[0].updatedMonitors).eql([]); expect(messages[0].failedMonitors).eql([ { - details: - 'Invalid value "3m" supplied to "schedule" | Invalid value "" supplied to "tags"', + details: 'Invalid value "3m" supplied to "schedule"', id: projectMonitors.monitors[0].id, payload: { content: @@ -492,6 +760,7 @@ export default function ({ getService }: FtrProviderContext) { latency: 20, upload: 3, }, + type: 'browser', }, reason: 'Failed to save or update monitor. Configuration is not valid', }, @@ -813,9 +1082,9 @@ export default function ({ getService }: FtrProviderContext) { privateLocations: ['Test private location 0'], }; const testMonitors = [projectMonitors.monitors[0], secondMonitor]; - const username = 'admin'; + const username = 'test-username'; const roleName = 'uptime read only'; - const password = `${username}-password`; + const password = `test-password`; try { await security.role.create(roleName, { kibana: [ @@ -1006,9 +1275,9 @@ export default function ({ getService }: FtrProviderContext) { const packagePolicy = apiResponsePolicy.body.items.find( (pkgPolicy: PackagePolicy) => pkgPolicy.id === - monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + - '-' + - testPolicyId + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` ); expect(packagePolicy.name).eql( `${projectMonitors.monitors[0].id}-${projectMonitors.project}-default-Test private location 0` @@ -1030,10 +1299,71 @@ export default function ({ getService }: FtrProviderContext) { } finally { await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + const packagesResponse = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + expect(packagesResponse.body.items.length).eql(0); + } + }); + + it('deletes integration policies for project monitors when private location is removed from the monitor - lightweight', async () => { + const monitorRequest = { + ...httpProjectMonitors, + monitors: [ + { ...httpProjectMonitors.monitors[1], privateLocations: ['Test private location 0'] }, + ], + }; + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) + .set('kbn-xsrf', 'true') + .send(monitorRequest); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitorRequest.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy.policy_id).eql(testPolicyId); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) + .set('kbn-xsrf', 'true') + .send({ + ...monitorRequest, + monitors: [{ ...monitorRequest.monitors[0], privateLocations: [] }], + }); + const apiResponsePolicy2 = await supertest.get( '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' ); - expect(apiResponsePolicy2.body.items.length).eql(0); + + const packagePolicy2 = apiResponsePolicy2.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy2).eql(undefined); + } finally { + await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); } }); @@ -1064,9 +1394,9 @@ export default function ({ getService }: FtrProviderContext) { const packagePolicy = apiResponsePolicy.body.items.find( (pkgPolicy: PackagePolicy) => pkgPolicy.id === - monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + - '-' + - testPolicyId + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` ); expect(packagePolicy.policy_id).eql(testPolicyId); @@ -1099,9 +1429,9 @@ export default function ({ getService }: FtrProviderContext) { const packagePolicy2 = apiResponsePolicy2.body.items.find( (pkgPolicy: PackagePolicy) => pkgPolicy.id === - monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + - '-' + - testPolicyId + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` ); expect(packagePolicy2).eql(undefined); @@ -1209,6 +1539,169 @@ export default function ({ getService }: FtrProviderContext) { } }); + it('deletes integration policies when project monitors are deleted - lightweight', async () => { + const monitorRequest = { + ...httpProjectMonitors, + monitors: [ + { ...httpProjectMonitors.monitors[1], privateLocations: ['Test private location 0'] }, + ], + }; + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) + .set('kbn-xsrf', 'true') + .send(monitorRequest); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitorRequest.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy.policy_id).eql(testPolicyId); + + const configId = monitorsResponse.body.monitors[0].id; + const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; + + const httpInput = packagePolicy.inputs.find( + (input: any) => input.type === 'synthetics/http' + ); + expect(httpInput).to.eql({ + type: 'synthetics/http', + policy_template: 'synthetics', + enabled: true, + streams: [ + { + enabled: true, + data_stream: { type: 'synthetics', dataset: 'http' }, + release: 'experimental', + vars: { + __ui: { value: '{"is_tls_enabled":false}', type: 'yaml' }, + enabled: { value: false, type: 'bool' }, + type: { value: 'http', type: 'text' }, + name: { value: 'My Monitor 3', type: 'text' }, + schedule: { value: '"@every 60m"', type: 'text' }, + urls: { value: 'http://localhost:9200', type: 'text' }, + 'service.name': { value: '', type: 'text' }, + timeout: { value: '80s', type: 'text' }, + max_redirects: { value: '0', type: 'integer' }, + proxy_url: { value: '', type: 'text' }, + tags: { value: '["tag2","tag2"]', type: 'yaml' }, + username: { value: '', type: 'text' }, + password: { value: '', type: 'password' }, + 'response.include_headers': { value: false, type: 'bool' }, + 'response.include_body': { value: 'always', type: 'text' }, + 'check.request.method': { value: 'POST', type: 'text' }, + 'check.request.headers': { + value: '{"Content-Type":"application/x-www-form-urlencoded"}', + type: 'yaml', + }, + 'check.request.body': { value: null, type: 'yaml' }, + 'check.response.status': { value: '["200"]', type: 'yaml' }, + 'check.response.headers': { value: null, type: 'yaml' }, + 'check.response.body.positive': { value: '["Saved","saved"]', type: 'yaml' }, + 'check.response.body.negative': { value: null, type: 'yaml' }, + 'ssl.certificate_authorities': { value: null, type: 'yaml' }, + 'ssl.certificate': { value: null, type: 'yaml' }, + 'ssl.key': { value: null, type: 'yaml' }, + 'ssl.key_passphrase': { value: null, type: 'text' }, + 'ssl.verification_mode': { value: 'full', type: 'text' }, + 'ssl.supported_protocols': { + value: '["TLSv1.1","TLSv1.2","TLSv1.3"]', + type: 'yaml', + }, + location_name: { value: 'Test private location 0', type: 'text' }, + id: { + value: id, + type: 'text', + }, + config_id: { value: configId, type: 'text' }, + run_once: { value: false, type: 'bool' }, + origin: { value: 'project', type: 'text' }, + }, + id: `synthetics/http-http-${id}-${testPolicyId}`, + compiled_stream: { + __ui: { is_tls_enabled: false }, + type: 'http', + name: 'My Monitor 3', + id, + origin: 'project', + enabled: false, + urls: 'http://localhost:9200', + schedule: '@every 60m', + timeout: '80s', + max_redirects: 0, + tags: ['tag2', 'tag2'], + 'response.include_headers': false, + 'response.include_body': 'always', + 'check.request.method': 'POST', + 'check.request.headers': { 'Content-Type': 'application/x-www-form-urlencoded' }, + 'check.response.status': ['200'], + 'check.response.body.positive': ['Saved', 'saved'], + 'ssl.verification_mode': 'full', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + processors: [ + { add_observer_metadata: { geo: { name: 'Test private location 0' } } }, + { + add_fields: { + target: '', + fields: { + 'monitor.fleet_managed': true, + config_id: configId, + }, + }, + }, + ], + }, + }, + ], + }); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) + .set('kbn-xsrf', 'true') + .send({ + ...monitorRequest, + monitors: [], + }); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy2 = apiResponsePolicy2.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + } - ${testPolicyId}` + ); + + expect(packagePolicy2).eql(undefined); + } finally { + await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + expect(apiResponsePolicy2.body.items.length).eql(0); + } + }); + it('handles updating package policies when project monitors are updated', async () => { try { await supertest diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json index 5f1f9cb8af017..76478fd7aee1a 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/http_monitor.json @@ -77,5 +77,6 @@ "namespace": "testnamespace", "revision": 1, "origin": "ui", - "form_monitor_type": "http" + "form_monitor_type": "http", + "journey_id": "" } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json index 3f2a25ea01ca0..d9df06d1c7c32 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/icmp_monitor.json @@ -1,6 +1,7 @@ { "type": "tcp", "locations": [], + "journey_id": "", "enabled": true, "schedule": { "number": "3", diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_browser_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_browser_monitor.json index f6709ab72066a..ba1101be34ba4 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_browser_monitor.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_browser_monitor.json @@ -1,27 +1,27 @@ { - "keep_stale": true, - "project": "test-suite", - "monitors": [{ - "throttling": { - "download": 5, - "upload": 3, - "latency": 20 - }, - "schedule": 10, - "locations": [ - "localhost" - ], - "params": {}, - "playwrightOptions": { - "headless": true, - "chromiumSandbox": false - }, - "name": "check if title is present", - "id": "check-if-title-is-present", - "tags": [], - "content": "UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA", - "filter": { - "match": "check if title is present" - } - }] + "keep_stale": true, + "project": "test-suite", + "monitors": [{ + "throttling": { + "download": 5, + "upload": 3, + "latency": 20 + }, + "schedule": 10, + "locations": [ + "localhost" + ], + "params": {}, + "playwrightOptions": { + "headless": true, + "chromiumSandbox": false + }, + "name": "check if title is present", + "id": "check-if-title-is-present", + "tags": [], + "content": "UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA", + "filter": { + "match": "check if title is present" + } + }] } diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_http_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_http_monitor.json new file mode 100644 index 0000000000000..fc754cbdcd038 --- /dev/null +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_http_monitor.json @@ -0,0 +1,76 @@ +{ + "project": "test-suite", + "keep_stale": false, + "monitors": [ + { + "locations": ["localhost"], + "type": "http", + "enabled": false, + "id": "my-monitor-2", + "name": "My Monitor 2", + "urls": [ + "http://localhost:9200" + ], + "schedule": 60, + "timeout": "80s", + "check.request": { + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + }, + "response": { + "include_body": "always" + }, + "response.include_headers": false, + "check.response": { + "status": [ + 200 + ], + "body": [ + "Saved", + "saved" + ] + }, + "content": "", + "unsupportedKey": { + "nestedUnsupportedKey": "unsupportedValue" + } + }, + { + "locations": ["localhost"], + "type": "http", + "enabled": false, + "id": "my-monitor-3", + "name": "My Monitor 3", + "urls": [ + "http://localhost:9200" + ], + "schedule": 60, + "timeout": "80s", + "check.request": { + "method": "POST", + "headers": { + "Content-Type": "application/x-www-form-urlencoded" + } + }, + "response": { + "include_body": "always" + }, + "tags": "tag2,tag2", + "response.include_headers": false, + "check.response": { + "status": [ + 200 + ], + "body":{ + "positive": [ + "Saved", + "saved" + ] + } + }, + "content": "" + } + ] +} \ No newline at end of file diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_icmp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_icmp_monitor.json new file mode 100644 index 0000000000000..8dec1b28d50c4 --- /dev/null +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_icmp_monitor.json @@ -0,0 +1,47 @@ + + + +{ + "project": "test-suite", + "keep_stale": true, + "monitors": [ + { + "locations": [ "localhost" ], + "type": "icmp", + "id": "Cloudflare-DNS", + "name": "Cloudflare DNS", + "hosts": [ "1.1.1.1" ], + "schedule": 1, + "tags": [ "service:smtp", "org:google" ], + "privateLocations": [ "Test private location 0" ], + "content": "", + "wait": "30s" + }, + { + "locations": [ "localhost" ], + "type": "icmp", + "id": "Cloudflare-DNS-2", + "name": "Cloudflare DNS 2", + "hosts": "1.1.1.1", + "schedule": 1, + "tags": "tag1,tag2", + "privateLocations": [ "Test private location 0" ], + "content": "", + "wait": "1m" + }, + { + "locations": [ "localhost" ], + "type": "icmp", + "id": "Cloudflare-DNS-3", + "name": "Cloudflare DNS 3", + "hosts": "1.1.1.1", + "schedule": 1, + "tags": "tag1,tag2", + "privateLocations": [ "Test private location 0" ], + "content": "", + "unsupportedKey": { + "nestedUnsupportedKey": "unnsuportedValue" + } + } + ] +} diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_tcp_monitor.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_tcp_monitor.json new file mode 100644 index 0000000000000..30061673079d3 --- /dev/null +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/project_tcp_monitor.json @@ -0,0 +1,43 @@ +{ + "project": "test-suite", + "keep_stale": true, + "monitors": [ + { + "locations": [ "localhost" ], + "type": "tcp", + "id": "gmail-smtp", + "name": "GMail SMTP", + "hosts": [ "smtp.gmail.com:587" ], + "schedule": 1, + "tags": [ "service:smtp", "org:google" ], + "privateLocations": [ "BEEP" ], + "content": "" + }, + { + "locations": [ "localhost" ], + "type": "tcp", + "id": "always-down", + "name": "Always Down", + "hosts": "localhost:18278", + "schedule": 1, + "tags": "tag1,tag2", + "privateLocations": [ "BEEP" ], + "content": "" + }, + { + "locations": [ "localhost" ], + "type": "tcp", + "id": "always-down", + "name": "Always Down", + "hosts": "localhost", + "ports": ["5698"], + "schedule": 1, + "tags": "tag1,tag2", + "privateLocations": [ "BEEP" ], + "content": "", + "unsupportedKey": { + "nestedUnsupportedKey": "unnsuportedValue" + } + } + ] +} diff --git a/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts index c622201091d71..b90014b657b4a 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts @@ -13,7 +13,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; import { getFixtureJson } from './helper/get_fixture_json'; export default function ({ getService }: FtrProviderContext) { - describe('[GET] /internal/uptime/service/monitors', function () { + describe('getSyntheticsMonitors', function () { this.tags('skipCloud'); const supertest = getService('supertest'); From 117d42c5258ffeca09abe21be807e584ec9eea0c Mon Sep 17 00:00:00 2001 From: Jordan <51442161+JordanSh@users.noreply.github.com> Date: Wed, 21 Sep 2022 00:23:22 +0300 Subject: [PATCH 18/55] [Cloud Posture] Benchmark new columns (#141150) --- .../cloud_security_posture/common/types.ts | 13 +--- .../get_enabled_csp_integration_details.ts | 24 +++++++ .../benchmarks/benchmarks_table.test.tsx | 19 ----- .../pages/benchmarks/benchmarks_table.tsx | 40 ++++++++--- .../public/pages/benchmarks/test_subjects.ts | 5 +- .../latest_findings_container.tsx | 6 +- .../findings_by_resource_container.tsx | 6 +- .../public/pages/rules/index.tsx | 30 +++----- .../fixtures/csp_benchmark_integration.ts | 19 +++++ .../routes/benchmarks/benchmarks.test.ts | 72 +------------------ .../server/routes/benchmarks/benchmarks.ts | 38 +++------- .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 14 files changed, 106 insertions(+), 172 deletions(-) create mode 100644 x-pack/plugins/cloud_security_posture/public/common/utils/get_enabled_csp_integration_details.ts diff --git a/x-pack/plugins/cloud_security_posture/common/types.ts b/x-pack/plugins/cloud_security_posture/common/types.ts index 21c33c7f2603a..f4d8573beb4c1 100644 --- a/x-pack/plugins/cloud_security_posture/common/types.ts +++ b/x-pack/plugins/cloud_security_posture/common/types.ts @@ -85,18 +85,7 @@ export interface CspRulesStatus { export type AgentPolicyStatus = Pick & { agents: number }; export interface Benchmark { - package_policy: Pick< - PackagePolicy, - | 'id' - | 'name' - | 'policy_id' - | 'namespace' - | 'package' - | 'updated_at' - | 'updated_by' - | 'created_at' - | 'created_by' - >; + package_policy: PackagePolicy; agent_policy: AgentPolicyStatus; rules: CspRulesStatus; } diff --git a/x-pack/plugins/cloud_security_posture/public/common/utils/get_enabled_csp_integration_details.ts b/x-pack/plugins/cloud_security_posture/public/common/utils/get_enabled_csp_integration_details.ts new file mode 100644 index 0000000000000..6cc02ac9aedc1 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/common/utils/get_enabled_csp_integration_details.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PackagePolicy } from '@kbn/fleet-plugin/common'; +import { cloudPostureIntegrations, CloudPostureIntegrations } from '../constants'; + +const isPolicyTemplate = (name: unknown): name is keyof CloudPostureIntegrations => + typeof name === 'string' && name in cloudPostureIntegrations; + +export const getEnabledCspIntegrationDetails = (packageInfo?: PackagePolicy) => { + const enabledInput = packageInfo?.inputs.find((input) => input.enabled); + if (!enabledInput || !isPolicyTemplate(enabledInput.policy_template)) return null; + + const integration = cloudPostureIntegrations[enabledInput.policy_template]; + const enabledIntegrationOption = integration.options.find( + (option) => option.type === enabledInput.type + ); + + return { integration, enabledIntegrationOption }; +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx index 463d19928db80..dc980df0d67ae 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.test.tsx @@ -42,25 +42,6 @@ describe('', () => { expect(screen.getByText(item.package_policy.name)).toBeInTheDocument(); }); - it('renders benchmark name', () => { - const item = createCspBenchmarkIntegrationFixture(); - const benchmarks = [item]; - - render( - - - - ); - - expect(screen.getByText(item.package_policy.package!.title)).toBeInTheDocument(); - }); - it('renders agent policy name', () => { const agentPolicy = { id: chance.guid(), diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx index 35dce429d54aa..df1a058de11b6 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks_table.tsx @@ -17,11 +17,13 @@ import React from 'react'; import { generatePath } from 'react-router-dom'; import { pagePathGetters } from '@kbn/fleet-plugin/public'; import { i18n } from '@kbn/i18n'; +import type { PackagePolicy } from '@kbn/fleet-plugin/common'; import { TimestampTableCell } from '../../components/timestamp_table_cell'; import type { Benchmark } from '../../../common/types'; import { useKibana } from '../../common/hooks/use_kibana'; import { cloudPosturePages } from '../../common/navigation/constants'; import * as TEST_SUBJ from './test_subjects'; +import { getEnabledCspIntegrationDetails } from '../../common/utils/get_enabled_csp_integration_details'; interface BenchmarksTableProps extends Pick, 'loading' | 'error' | 'noItemsMessage' | 'sorting'>, @@ -66,8 +68,8 @@ const IntegrationButtonLink = ({ const BENCHMARKS_TABLE_COLUMNS: Array> = [ { field: 'package_policy.name', - name: i18n.translate('xpack.csp.benchmarks.benchmarksTable.integrationColumnTitle', { - defaultMessage: 'Integration', + name: i18n.translate('xpack.csp.benchmarks.benchmarksTable.integrationNameColumnTitle', { + defaultMessage: 'Integration Name', }), render: (packageName, benchmark) => ( > = [ ), truncateText: true, sortable: true, - 'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.INTEGRATION, + 'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.INTEGRATION_NAME, }, { field: 'rules.enabled', - name: i18n.translate('xpack.csp.benchmarks.benchmarksTable.activeRulesColumnTitle', { - defaultMessage: 'Active Rules', + name: i18n.translate('xpack.csp.benchmarks.benchmarksTable.rulesColumnTitle', { + defaultMessage: 'Rules', + }), + truncateText: true, + 'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.RULES, + }, + { + field: 'package_policy', + name: i18n.translate('xpack.csp.benchmarks.benchmarksTable.integrationColumnTitle', { + defaultMessage: 'Integration', }), + dataType: 'string', truncateText: true, - 'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.ACTIVE_RULES, + sortable: true, + 'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.INTEGRATION, + render: (field: PackagePolicy) => { + const enabledIntegration = getEnabledCspIntegrationDetails(field); + return enabledIntegration?.integration?.shortName || ' '; + }, }, { - field: 'package_policy.package.title', - name: i18n.translate('xpack.csp.benchmarks.benchmarksTable.integrationTypeColumnTitle', { - defaultMessage: 'Integration Type', + field: 'package_policy', + name: i18n.translate('xpack.csp.benchmarks.benchmarksTable.deploymentTypeColumnTitle', { + defaultMessage: 'Deployment Type', }), dataType: 'string', truncateText: true, sortable: true, - 'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.INTEGRATION_TYPE, + 'data-test-subj': TEST_SUBJ.BENCHMARKS_TABLE_COLUMNS.DEPLOYMENT_TYPE, + render: (field: PackagePolicy) => { + const enabledIntegration = getEnabledCspIntegrationDetails(field); + return enabledIntegration?.enabledIntegrationOption?.name || ' '; + }, }, { field: 'agent_policy.name', diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/test_subjects.ts b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/test_subjects.ts index 3680c92f5d42b..d1d27325f9f88 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/test_subjects.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/test_subjects.ts @@ -9,9 +9,10 @@ export const BENCHMARKS_PAGE_HEADER = 'benchmarks-page-header'; export const BENCHMARKS_TABLE_DATA_TEST_SUBJ = 'csp_benchmarks_table'; export const ADD_INTEGRATION_TEST_SUBJ = 'csp_add_integration'; export const BENCHMARKS_TABLE_COLUMNS = { + INTEGRATION_NAME: 'benchmarks-table-column-integration-name', + DEPLOYMENT_TYPE: 'benchmarks-table-column-deployment-type', + RULES: 'benchmarks-table-column-rules', INTEGRATION: 'benchmarks-table-column-integration', - ACTIVE_RULES: 'benchmarks-table-column-active-rules', - INTEGRATION_TYPE: 'benchmarks-table-column-integration_type', AGENT_POLICY: 'benchmarks-table-column-agent-policy', NUMBER_OF_AGENTS: 'benchmarks-table-column-number-of-agents', CREATED_BY: 'benchmarks-table-column-created-by', diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx index 9ef90e0ddecbb..3294ee8ec4965 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx @@ -104,10 +104,12 @@ export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => { loading={findingsGroupByNone.isFetching} /> - + - {!error && } + + {!error && } + {error && } {!error && ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx index efebc3e83b2a5..e9ce59fe9f0c0 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx @@ -104,7 +104,7 @@ const LatestFindingsByResource = ({ dataView }: FindingsBaseProps) => { loading={findingsGroupByResource.isFetching} /> - + { /> - {!error && } + + {!error && } + {error && } {!error && ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx index 0e94d41a47127..edb41a0535f16 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/index.tsx @@ -29,8 +29,8 @@ import { useCspIntegrationInfo } from './use_csp_integration'; import { useKibana } from '../../common/hooks/use_kibana'; import { CloudPosturePage } from '../../components/cloud_posture_page'; import { SecuritySolutionContext } from '../../application/security_solution_context'; -import { CloudPostureIntegrations, cloudPostureIntegrations } from '../../common/constants'; import * as TEST_SUBJECTS from './test_subjects'; +import { getEnabledCspIntegrationDetails } from '../../common/utils/get_enabled_csp_integration_details'; const getRulesBreadcrumbs = ( name?: string, @@ -52,43 +52,35 @@ const getRulesBreadcrumbs = ( return breadCrumbs; }; -const isPolicyTemplate = (name: unknown): name is keyof CloudPostureIntegrations => - typeof name === 'string' && name in cloudPostureIntegrations; - const getRulesSharedValues = ( packageInfo?: PackagePolicy ): NonNullable => { - const enabledInput = packageInfo?.inputs.find((input) => input.enabled); - if (!enabledInput || !isPolicyTemplate(enabledInput.policy_template)) return []; - - const integration = cloudPostureIntegrations[enabledInput.policy_template]; - const enabledIntegrationOption = integration.options.find( - (option) => option.type === enabledInput.type - ); + const enabledIntegration = getEnabledCspIntegrationDetails(packageInfo); + const values = []; - const values = [ - { + if (enabledIntegration?.integration?.shortName) { + values.push({ title: i18n.translate('xpack.csp.rules.rulesPageSharedValues.integrationTitle', { defaultMessage: 'Integration', }), - description: integration.shortName, - }, - ]; + description: enabledIntegration?.integration.shortName, + }); + } - if (!enabledIntegrationOption) return values; + if (!enabledIntegration?.enabledIntegrationOption) return values; values.push( { title: i18n.translate('xpack.csp.rules.rulesPageSharedValues.deploymentTypeTitle', { defaultMessage: 'Deployment Type', }), - description: enabledIntegrationOption.name, + description: enabledIntegration?.enabledIntegrationOption.name, }, { title: i18n.translate('xpack.csp.rules.rulesPageSharedValues.benchmarkTitle', { defaultMessage: 'Benchmark', }), - description: enabledIntegrationOption.benchmark, + description: enabledIntegration?.enabledIntegrationOption.benchmark, } ); diff --git a/x-pack/plugins/cloud_security_posture/public/test/fixtures/csp_benchmark_integration.ts b/x-pack/plugins/cloud_security_posture/public/test/fixtures/csp_benchmark_integration.ts index 2f05049c4fe15..496b73f7bbef0 100644 --- a/x-pack/plugins/cloud_security_posture/public/test/fixtures/csp_benchmark_integration.ts +++ b/x-pack/plugins/cloud_security_posture/public/test/fixtures/csp_benchmark_integration.ts @@ -17,6 +17,8 @@ type CreateCspBenchmarkIntegrationFixtureInput = { export const createCspBenchmarkIntegrationFixture = ({ chance = new Chance(), package_policy = { + revision: chance?.integer(), + enabled: true, id: chance.guid(), name: chance.string(), policy_id: chance.guid(), @@ -25,6 +27,23 @@ export const createCspBenchmarkIntegrationFixture = ({ updated_by: chance.word(), created_at: chance.date().toISOString(), created_by: chance.word(), + inputs: [ + { + type: 'cloudbeat/cis_k8s', + policy_template: 'kspm', + enabled: true, + streams: [ + { + id: chance?.guid(), + enabled: true, + data_stream: { + type: 'logs', + dataset: 'cloud_security_posture.findings', + }, + }, + ], + }, + ], package: { name: chance.string(), title: chance.string(), diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts index a950741ea2d8f..49c392d724c25 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.test.ts @@ -14,11 +14,7 @@ import { getCspPackagePolicies, getCspAgentPolicies, } from '../../lib/fleet_util'; -import { - defineGetBenchmarksRoute, - createBenchmarkEntry, - addPackagePolicyCspRules, -} from './benchmarks'; +import { defineGetBenchmarksRoute, addPackagePolicyCspRules } from './benchmarks'; import { SavedObjectsClientContract, SavedObjectsFindResponse } from '@kbn/core/server'; import { @@ -26,28 +22,8 @@ import { createPackagePolicyServiceMock, } from '@kbn/fleet-plugin/server/mocks'; import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks'; -import { AgentPolicy } from '@kbn/fleet-plugin/common'; import { createCspRequestHandlerContextMock } from '../../mocks'; -function createMockAgentPolicy(props: Partial = {}): AgentPolicy { - return { - id: 'some-uuid1', - namespace: 'default', - monitoring_enabled: [], - name: 'Test Policy', - description: '', - is_default: false, - is_preconfigured: false, - status: 'active', - is_managed: false, - revision: 1, - updated_at: '', - updated_by: 'elastic', - package_policies: [], - ...props, - }; -} - describe('benchmarks API', () => { beforeEach(() => { jest.clearAllMocks(); @@ -307,51 +283,5 @@ describe('benchmarks API', () => { }); }); }); - - describe('test createBenchmarkEntry', () => { - it('should build benchmark entry agent policy and package policy', async () => { - const packagePolicy = createPackagePolicyMock(); - const agentPolicy = createMockAgentPolicy(); - - const cspRulesStatus = { - all: 100, - enabled: 52, - disabled: 48, - }; - const enrichAgentPolicy = await createBenchmarkEntry( - { - id: agentPolicy.id, - name: agentPolicy.name, - agents: 3, - }, - packagePolicy, - cspRulesStatus - ); - - expect(enrichAgentPolicy).toEqual({ - package_policy: { - id: 'c6d16e42-c32d-4dce-8a88-113cfe276ad1', - name: 'endpoint-1', - policy_id: '93c46720-c217-11ea-9906-b5b8a21b268e', - namespace: 'default', - updated_at: '2020-06-25T16:03:38.159292', - updated_by: 'kibana', - created_at: '2020-06-25T16:03:38.159292', - created_by: 'kibana', - package: { - name: 'endpoint', - title: 'Elastic Endpoint', - version: '0.9.0', - }, - }, - agent_policy: { id: 'some-uuid1', name: 'Test Policy', agents: 3 }, - rules: { - all: 100, - disabled: 48, - enabled: 52, - }, - }); - }); - }); }); }); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts index 4bc00f5e0209d..dec553cee6f75 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts @@ -13,7 +13,7 @@ import { CSP_RULE_SAVED_OBJECT_TYPE, } from '../../../common/constants'; import { benchmarksQueryParamsSchema } from '../../../common/schemas/benchmark'; -import type { Benchmark, CspRulesStatus, AgentPolicyStatus } from '../../../common/types'; +import type { Benchmark, CspRulesStatus } from '../../../common/types'; import type { CspRule } from '../../../common/schemas'; import { createCspRuleSearchFilterByPackagePolicy, @@ -74,32 +74,6 @@ export const addPackagePolicyCspRules = async ( return packagePolicyRules; }; -export const createBenchmarkEntry = ( - agentPolicyStatus: AgentPolicyStatus, - packagePolicy: PackagePolicy, - cspRulesStatus: CspRulesStatus -): Benchmark => ({ - package_policy: { - id: packagePolicy.id, - name: packagePolicy.name, - policy_id: packagePolicy.policy_id, - namespace: packagePolicy.namespace, - updated_at: packagePolicy.updated_at, - updated_by: packagePolicy.updated_by, - created_at: packagePolicy.created_at, - created_by: packagePolicy.created_by, - package: packagePolicy.package - ? { - name: packagePolicy.package.name, - title: packagePolicy.package.title, - version: packagePolicy.package.version, - } - : undefined, - }, - agent_policy: agentPolicyStatus, - rules: cspRulesStatus, -}); - const createBenchmarks = ( soClient: SavedObjectsClientContract, agentPolicies: AgentPolicy[], @@ -109,6 +83,7 @@ const createBenchmarks = ( const cspPackagePoliciesMap = new Map( cspPackagePolicies.map((packagePolicy) => [packagePolicy.id, packagePolicy]) ); + return Promise.all( agentPolicies.flatMap((agentPolicy) => { const cspPackagesOnAgent = @@ -117,6 +92,7 @@ const createBenchmarks = ( return cspPackagePoliciesMap.get(pckPolicyId); }) .filter(isNonNullable) ?? []; + const benchmarks = cspPackagesOnAgent.map(async (cspPackage) => { const cspRulesStatus = await addPackagePolicyCspRules(soClient, cspPackage); const agentPolicyStatus = { @@ -124,8 +100,12 @@ const createBenchmarks = ( name: agentPolicy.name, agents: agentStatusByAgentPolicyId[agentPolicy.id].total, }; - const benchmark = createBenchmarkEntry(agentPolicyStatus, cspPackage, cspRulesStatus); - return benchmark; + + return { + package_policy: cspPackage, + agent_policy: agentPolicyStatus, + rules: cspRulesStatus, + }; }); return benchmarks; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index d069b09dd3c65..8b5324cdd51fc 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -9542,12 +9542,10 @@ "xpack.csp.benchmarks.benchmarkEmptyState.integrationsNotFoundWithFiltersTitle": "Nous n'avons trouvé aucune intégration Benchmark avec les filtres ci-dessus.", "xpack.csp.benchmarks.benchmarkSearchField.searchPlaceholder": "par exemple, le nom d'un benchmark", "xpack.csp.benchmarks.benchmarksPageHeader.benchmarkIntegrationsTitle": "Intégrations Benchmark", - "xpack.csp.benchmarks.benchmarksTable.activeRulesColumnTitle": "Règles actives", "xpack.csp.benchmarks.benchmarksTable.agentPolicyColumnTitle": "Politique d'agent", "xpack.csp.benchmarks.benchmarksTable.createdAtColumnTitle": "Créé à", "xpack.csp.benchmarks.benchmarksTable.createdByColumnTitle": "Créé par", "xpack.csp.benchmarks.benchmarksTable.integrationColumnTitle": "Intégration", - "xpack.csp.benchmarks.benchmarksTable.integrationTypeColumnTitle": "Type d'intégration", "xpack.csp.benchmarks.benchmarksTable.numberOfAgentsColumnTitle": "Nombre d'agents", "xpack.csp.cloudPosturePage.defaultNoDataConfig.pageTitle": "Aucune donnée trouvée", "xpack.csp.cloudPosturePage.defaultNoDataConfig.solutionNameLabel": "Niveau de sécurité du cloud", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index a6f22902ac9ed..106718f0c2ade 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9529,12 +9529,10 @@ "xpack.csp.benchmarks.benchmarkEmptyState.integrationsNotFoundWithFiltersTitle": "上記のフィルターでベンチマーク統合が見つかりませんでした。", "xpack.csp.benchmarks.benchmarkSearchField.searchPlaceholder": "例:ベンチマーク名", "xpack.csp.benchmarks.benchmarksPageHeader.benchmarkIntegrationsTitle": "ベンチマーク統合", - "xpack.csp.benchmarks.benchmarksTable.activeRulesColumnTitle": "アクティブなルール", "xpack.csp.benchmarks.benchmarksTable.agentPolicyColumnTitle": "エージェントポリシー", "xpack.csp.benchmarks.benchmarksTable.createdAtColumnTitle": "作成日時:", "xpack.csp.benchmarks.benchmarksTable.createdByColumnTitle": "作成者", "xpack.csp.benchmarks.benchmarksTable.integrationColumnTitle": "統合", - "xpack.csp.benchmarks.benchmarksTable.integrationTypeColumnTitle": "統合タイプ", "xpack.csp.benchmarks.benchmarksTable.numberOfAgentsColumnTitle": "エージェント数", "xpack.csp.cloudPosturePage.defaultNoDataConfig.pageTitle": "データが見つかりません", "xpack.csp.cloudPosturePage.defaultNoDataConfig.solutionNameLabel": "クラウドセキュリティ態勢", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 315476cde96fa..553d66f841859 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9544,12 +9544,10 @@ "xpack.csp.benchmarks.benchmarkEmptyState.integrationsNotFoundWithFiltersTitle": "使用上述筛选,我们无法找到任何基准集成。", "xpack.csp.benchmarks.benchmarkSearchField.searchPlaceholder": "例如,基准名称", "xpack.csp.benchmarks.benchmarksPageHeader.benchmarkIntegrationsTitle": "基准集成", - "xpack.csp.benchmarks.benchmarksTable.activeRulesColumnTitle": "活动规则", "xpack.csp.benchmarks.benchmarksTable.agentPolicyColumnTitle": "代理策略", "xpack.csp.benchmarks.benchmarksTable.createdAtColumnTitle": "创建于", "xpack.csp.benchmarks.benchmarksTable.createdByColumnTitle": "创建者", "xpack.csp.benchmarks.benchmarksTable.integrationColumnTitle": "集成", - "xpack.csp.benchmarks.benchmarksTable.integrationTypeColumnTitle": "集成类型", "xpack.csp.benchmarks.benchmarksTable.numberOfAgentsColumnTitle": "代理数目", "xpack.csp.cloudPosturePage.defaultNoDataConfig.pageTitle": "未找到任何数据", "xpack.csp.cloudPosturePage.defaultNoDataConfig.solutionNameLabel": "云安全态势", From cffa4deda6cc6af6235935649d2b109c831e5e80 Mon Sep 17 00:00:00 2001 From: Ashokaditya <1849116+ashokaditya@users.noreply.github.com> Date: Tue, 20 Sep 2022 23:24:33 +0200 Subject: [PATCH 19/55] [Security Solution][Endpoint][Response Actions] Add users filter to actions log (#140975) * Add users filter to actions log fixes elastic/security-team/issues/4724 * Add tests fixes elastic/security-team/issues/4724 * update test fixes elastic/security-team/issues/4724 --- .../components/actions_log_filters.tsx | 10 ++- .../actions_log_users_filter.test.tsx | 87 +++++++++++++++++++ .../components/actions_log_users_filter.tsx | 79 +++++++++++++++++ .../use_action_history_url_params.test.ts | 43 ++++++--- .../response_actions_log.tsx | 14 ++- .../translations.tsx | 4 +- .../view/response_actions_list_page.test.tsx | 24 ++++- 7 files changed, 243 insertions(+), 18 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_users_filter.test.tsx create mode 100644 x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_users_filter.tsx diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx index 564a8f0d8e084..9fb8cce0f291a 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx @@ -16,6 +16,7 @@ import { ActionLogDateRangePicker, } from './actions_log_date_range_picker'; import { ActionsLogFilter } from './actions_log_filter'; +import { ActionsLogUsersFilter } from './actions_log_users_filter'; import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; export const ActionsLogFilters = memo( @@ -27,6 +28,7 @@ export const ActionsLogFilters = memo( onChangeHostsFilter, onChangeCommandsFilter, onChangeStatusesFilter, + onChangeUsersFilter, onRefresh, onRefreshChange, onTimeChange, @@ -38,6 +40,7 @@ export const ActionsLogFilters = memo( onChangeHostsFilter: (selectedCommands: string[]) => void; onChangeCommandsFilter: (selectedCommands: string[]) => void; onChangeStatusesFilter: (selectedStatuses: string[]) => void; + onChangeUsersFilter: (selectedUsers: string[]) => void; onRefresh: () => void; onRefreshChange: (evt: OnRefreshChangeProps) => void; onTimeChange: ({ start, end }: DurationRange) => void; @@ -79,10 +82,13 @@ export const ActionsLogFilters = memo( return ( - + + + + {filters} - + { + let render: ( + props?: React.ComponentProps + ) => ReturnType; + let renderResult: ReturnType; + let history: AppContextTestRender['history']; + let mockedContext: AppContextTestRender; + + const testPrefix = 'response-actions-list-users-filter'; + let onChangeUsersFilter: jest.Mock; + + beforeEach(async () => { + onChangeUsersFilter = jest.fn(); + mockedContext = createAppRootMockRenderer(); + ({ history } = mockedContext); + render = (props?: React.ComponentProps) => + (renderResult = mockedContext.render( + + )); + reactTestingLibrary.act(() => { + history.push(`${MANAGEMENT_PATH}/response_actions`); + }); + }); + + it('should show a search input for users', () => { + render(); + + const searchInput = renderResult.getByTestId(`${testPrefix}-search`); + expect(searchInput).toBeTruthy(); + expect(searchInput.getAttribute('placeholder')).toEqual( + 'Filter by user or comma separated list of users' + ); + }); + + it('should search on given search string on enter', () => { + render(); + + const searchInput = renderResult.getByTestId(`${testPrefix}-search`); + userEvent.type(searchInput, 'usernameX'); + userEvent.type(searchInput, '{enter}'); + expect(onChangeUsersFilter).toHaveBeenCalledWith(['usernameX']); + }); + + it('should search comma separated strings as multiple users', () => { + render(); + + const searchInput = renderResult.getByTestId(`${testPrefix}-search`); + userEvent.type(searchInput, 'usernameX,usernameY,usernameZ'); + userEvent.type(searchInput, '{enter}'); + expect(onChangeUsersFilter).toHaveBeenCalledWith(['usernameX', 'usernameY', 'usernameZ']); + }); + + it('should ignore white spaces in a given username when updating the API params', () => { + render(); + + const searchInput = renderResult.getByTestId(`${testPrefix}-search`); + userEvent.type(searchInput, ' usernameX '); + userEvent.type(searchInput, '{enter}'); + expect(onChangeUsersFilter).toHaveBeenCalledWith(['usernameX']); + }); + + it('should ignore white spaces in comma separated usernames when updating the API params', () => { + render(); + + const searchInput = renderResult.getByTestId(`${testPrefix}-search`); + userEvent.type(searchInput, ' , usernameX ,usernameY , '); + userEvent.type(searchInput, '{enter}'); + expect(onChangeUsersFilter).toHaveBeenCalledWith(['usernameX', 'usernameY']); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_users_filter.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_users_filter.tsx new file mode 100644 index 0000000000000..d9de7986c5e80 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_users_filter.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback, useState, useEffect } from 'react'; +import { EuiFieldSearch, EuiFormControlLayout } from '@elastic/eui'; +import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; +import { FILTER_NAMES } from '../translations'; +import { useActionHistoryUrlParams } from './use_action_history_url_params'; + +export const ActionsLogUsersFilter = memo( + ({ + isFlyout, + onChangeUsersFilter, + }: { + isFlyout: boolean; + onChangeUsersFilter: (selectedUserIds: string[]) => void; + }) => { + const getTestId = useTestIdGenerator('response-actions-list'); + const { users: usersFromUrlParams, setUrlUsersFilters } = useActionHistoryUrlParams(); + const [searchValue, setSearchValue] = useState(''); + + const onChange = useCallback( + (e: React.ChangeEvent) => { + setSearchValue(e.target.value); + }, + [setSearchValue] + ); + + const onSearch = useCallback(() => { + const userIds = searchValue.split(',').reduce((acc, curr) => { + if (curr.trim() !== '') { + acc.push(curr.trim()); + } + return acc; + }, []); + onChangeUsersFilter(userIds); + if (!isFlyout) { + setUrlUsersFilters(userIds.join(',')); + } + }, [isFlyout, onChangeUsersFilter, searchValue, setUrlUsersFilters]); + + const onClear = useCallback(() => { + setSearchValue(''); + onChangeUsersFilter([]); + if (!isFlyout) { + setUrlUsersFilters(''); + } + }, [isFlyout, onChangeUsersFilter, setUrlUsersFilters, setSearchValue]); + + // on load with users in urlParams, set the search value + useEffect(() => { + if (usersFromUrlParams && usersFromUrlParams.length > 0) { + setSearchValue(usersFromUrlParams.join(',')); + } + // do this only once on load + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + + + + ); + } +); + +ActionsLogUsersFilter.displayName = 'ActionsLogUsersFilter'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/use_action_history_url_params.test.ts b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/use_action_history_url_params.test.ts index 6f22b512d1bf1..5b62dbe814d3c 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/use_action_history_url_params.test.ts +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/use_action_history_url_params.test.ts @@ -7,7 +7,7 @@ import { actionsLogFiltersFromUrlParams } from './use_action_history_url_params'; describe('#actionsLogFiltersFromUrlParams', () => { - it('should not use invalid command values to URL params', () => { + it('should not use invalid command values from URL params', () => { expect(actionsLogFiltersFromUrlParams({ commands: 'asa,was' })).toEqual({ commands: undefined, endDate: undefined, @@ -18,7 +18,7 @@ describe('#actionsLogFiltersFromUrlParams', () => { }); }); - it('should use valid command values to URL params', () => { + it('should use valid command values from URL params', () => { expect( actionsLogFiltersFromUrlParams({ commands: 'kill-process,isolate,processes,release,suspend-process', @@ -33,7 +33,7 @@ describe('#actionsLogFiltersFromUrlParams', () => { }); }); - it('should not use invalid status values to URL params', () => { + it('should not use invalid status values from URL params', () => { expect(actionsLogFiltersFromUrlParams({ statuses: 'asa,was' })).toEqual({ commands: undefined, endDate: undefined, @@ -44,7 +44,7 @@ describe('#actionsLogFiltersFromUrlParams', () => { }); }); - it('should use valid status values to URL params', () => { + it('should use valid status values from URL params', () => { expect( actionsLogFiltersFromUrlParams({ statuses: 'successful,pending,failed', @@ -59,23 +59,27 @@ describe('#actionsLogFiltersFromUrlParams', () => { }); }); - it('should use valid command and status values to URL params', () => { + it('should use valid command and status along with given host, user and date values from URL params', () => { expect( actionsLogFiltersFromUrlParams({ commands: 'release,kill-process,isolate,processes,suspend-process', statuses: 'successful,pending,failed', + hosts: 'host-1,host-2', + users: 'user-1,user-2', + startDate: '2022-09-12T08:00:00.000Z', + endDate: '2022-09-12T08:30:33.140Z', }) ).toEqual({ commands: ['isolate', 'kill-process', 'processes', 'release', 'suspend-process'], - endDate: undefined, - hosts: undefined, - startDate: undefined, + endDate: '2022-09-12T08:30:33.140Z', + hosts: ['host-1', 'host-2'], + startDate: '2022-09-12T08:00:00.000Z', statuses: ['failed', 'pending', 'successful'], - users: undefined, + users: ['user-1', 'user-2'], }); }); - it('should use set given relative startDate and endDate values to URL params', () => { + it('should use given relative startDate and endDate values URL params', () => { expect( actionsLogFiltersFromUrlParams({ startDate: 'now-24h/h', @@ -91,7 +95,7 @@ describe('#actionsLogFiltersFromUrlParams', () => { }); }); - it('should use set given absolute startDate and endDate values to URL params', () => { + it('should use given absolute startDate and endDate values URL params', () => { expect( actionsLogFiltersFromUrlParams({ startDate: '2022-09-12T08:00:00.000Z', @@ -107,7 +111,7 @@ describe('#actionsLogFiltersFromUrlParams', () => { }); }); - it('should use set given hosts values to URL params', () => { + it('should use given hosts values from URL params', () => { expect( actionsLogFiltersFromUrlParams({ hosts: 'agent-id-1,agent-id-2', @@ -121,4 +125,19 @@ describe('#actionsLogFiltersFromUrlParams', () => { users: undefined, }); }); + + it('should use given users values from URL params', () => { + expect( + actionsLogFiltersFromUrlParams({ + users: 'usernameA,usernameB', + }) + ).toEqual({ + commands: undefined, + endDate: undefined, + hosts: undefined, + startDate: undefined, + statuses: undefined, + users: ['usernameA', 'usernameB'], + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx index e985aae704ebf..d7b923dec5058 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx @@ -127,6 +127,7 @@ export const ResponseActionsLog = memo< statuses: statusesFromUrl, startDate: startDateFromUrl, endDate: endDateFromUrl, + users: usersFromUrl, } = useActionHistoryUrlParams(); const getTestId = useTestIdGenerator('response-actions-list'); @@ -158,9 +159,10 @@ export const ResponseActionsLog = memo< statuses: statusesFromUrl?.length ? (statusesFromUrl as ResponseActionStatus[]) : prevState.statuses, + userIds: usersFromUrl?.length ? usersFromUrl : prevState.userIds, })); } - }, [commandsFromUrl, agentIdsFromUrl, isFlyout, statusesFromUrl, setQueryParams]); + }, [commandsFromUrl, agentIdsFromUrl, isFlyout, statusesFromUrl, setQueryParams, usersFromUrl]); // date range picker state and handlers const { dateRangePickerState, onRefreshChange, onTimeChange } = useDateRangePicker(isFlyout); @@ -237,6 +239,15 @@ export const ResponseActionsLog = memo< }, [setQueryParams] ); + + // handle on change users filter + const onChangeUsersFilter = useCallback( + (selectedUserIds: string[]) => { + setQueryParams((prevState) => ({ ...prevState, userIds: selectedUserIds })); + }, + [setQueryParams] + ); + // total actions const totalItemCount = useMemo(() => actionList?.total ?? 0, [actionList]); @@ -622,6 +633,7 @@ export const ResponseActionsLog = memo< onChangeHostsFilter={onChangeHostsFilter} onChangeCommandsFilter={onChangeCommandsFilter} onChangeStatusesFilter={onChangeStatusesFilter} + onChangeUsersFilter={onChangeUsersFilter} onRefresh={onRefresh} onRefreshChange={onRefreshChange} onTimeChange={onTimeChange} diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx index 9efc4356c21a2..542f0d72bf0be 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/translations.tsx @@ -160,7 +160,6 @@ export const UX_MESSAGES = Object.freeze({ }), }); -// TODO: Add more filter names here (hosts, statuses) etc export const FILTER_NAMES = Object.freeze({ actions: i18n.translate('xpack.securitySolution.responseActionsList.list.filter.actions', { defaultMessage: 'Actions', @@ -171,4 +170,7 @@ export const FILTER_NAMES = Object.freeze({ statuses: i18n.translate('xpack.securitySolution.responseActionsList.list.filter.statuses', { defaultMessage: 'Statuses', }), + users: i18n.translate('xpack.securitySolution.responseActionsList.list.filter.users', { + defaultMessage: 'Filter by user or comma separated list of users', + }), }); 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 c7f6315c9d9d4..734db973826c9 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 @@ -290,7 +290,18 @@ describe('Action history page', () => { expect(history.location.search).toEqual('?statuses=pending,failed'); }); - // TODO: add tests for users when that filter is added + it('should set selected users search input strings to URL params ', () => { + const filterPrefix = 'users-filter'; + reactTestingLibrary.act(() => { + history.push('/administration/action_history?users=userX,userY'); + }); + + render(); + const { getByTestId } = renderResult; + const usersInput = getByTestId(`${testPrefix}-${filterPrefix}-search`); + expect(usersInput).toHaveValue('userX,userY'); + expect(history.location.search).toEqual('?users=userX,userY'); + }); it('should read and set relative date ranges filter values from URL params', () => { reactTestingLibrary.act(() => { @@ -398,7 +409,16 @@ describe('Action history page', () => { expect(history.location.search).toEqual('?statuses=failed%2Cpending%2Csuccessful'); }); - // TODO: add tests for users when that filter is added + it('should set selected users search input strings to URL params ', () => { + const filterPrefix = 'users-filter'; + render(); + const { getByTestId } = renderResult; + const usersInput = getByTestId(`${testPrefix}-${filterPrefix}-search`); + userEvent.type(usersInput, ' , userX , userY, ,'); + userEvent.type(usersInput, '{enter}'); + + expect(history.location.search).toEqual('?users=userX%2CuserY'); + }); it('should set selected relative date range filter options to URL params ', async () => { const { getByTestId } = render(); From 50b3381e75516069772bb82c987db223d339e393 Mon Sep 17 00:00:00 2001 From: Paulo Henrique Date: Tue, 20 Sep 2022 14:42:25 -0700 Subject: [PATCH 20/55] [8.5][Elastic Defend onboarding][Event Filters] Add process.entry_leader.interactive to the Exception List (#141148) --- .../endpoint/exceptions/exceptionable_endpoint_event_fields.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/security_solution/common/endpoint/exceptions/exceptionable_endpoint_event_fields.ts b/x-pack/plugins/security_solution/common/endpoint/exceptions/exceptionable_endpoint_event_fields.ts index 38cbee8d70d8f..2c7b9d332072f 100644 --- a/x-pack/plugins/security_solution/common/endpoint/exceptions/exceptionable_endpoint_event_fields.ts +++ b/x-pack/plugins/security_solution/common/endpoint/exceptions/exceptionable_endpoint_event_fields.ts @@ -205,6 +205,7 @@ export const EXCEPTIONABLE_ENDPOINT_EVENT_FIELDS = [ 'process.command_line.caseless', 'process.command_line.text', 'process.entity_id', + 'process.entry_leader.interactive', 'process.executable', 'process.executable.caseless', 'process.executable.text', From 17a25b8230bbf68f0c74754eaed872a7bd36f274 Mon Sep 17 00:00:00 2001 From: Ersin Erdal <92688503+ersin-erdal@users.noreply.github.com> Date: Tue, 20 Sep 2022 23:43:00 +0200 Subject: [PATCH 21/55] Add new telemetry data from event-log index. (#140943) * Add new telemetry data from eventLog index. count_rules_by_execution_status_per_day, count_connector_types_by_action_run_outcome_per_day, --- .../server/usage/actions_telemetry.test.ts | 41 +++++++++ .../actions/server/usage/actions_telemetry.ts | 50 ++++++++++- .../server/usage/actions_usage_collector.ts | 8 ++ .../lib/parse_connector_type_bucket.test.ts | 88 +++++++++++++++++++ .../usage/lib/parse_connector_type_bucket.ts | 30 +++++++ x-pack/plugins/actions/server/usage/task.ts | 2 + x-pack/plugins/actions/server/usage/types.ts | 1 + .../server/usage/alerting_usage_collector.ts | 9 ++ .../lib/get_telemetry_from_event_log.test.ts | 14 ++- .../usage/lib/get_telemetry_from_event_log.ts | 21 ++++- x-pack/plugins/alerting/server/usage/task.ts | 2 + x-pack/plugins/alerting/server/usage/types.ts | 1 + .../schema/xpack_plugins.json | 30 +++++++ .../alerting_and_actions_telemetry.ts | 7 ++ 14 files changed, 300 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.test.ts create mode 100644 x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.ts diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts index b5606543b04e5..7216f627ea783 100644 --- a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts +++ b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts @@ -721,6 +721,36 @@ Object { }, }, }, + count_connector_types_by_action_run_outcome_per_day: { + actionSavedObjects: { + connector_types: { + buckets: [ + { + key: '.slack', + outcome: { + count: { + buckets: [ + { key: 'success', doc_count: 12 }, + { key: 'failure', doc_count: 1 }, + ], + }, + }, + }, + { + key: '.email', + outcome: { + count: { + buckets: [ + { key: 'success', doc_count: 13 }, + { key: 'failure', doc_count: 2 }, + ], + }, + }, + }, + ], + }, + }, + }, }, } ); @@ -754,6 +784,16 @@ Object { __slack: 7, }, countTotal: 120, + countRunOutcomeByConnectorType: { + __email: { + failure: 2, + success: 13, + }, + __slack: { + failure: 1, + success: 12, + }, + }, hasErrors: false, }); }); @@ -775,6 +815,7 @@ Object { "countByType": Object {}, "countFailed": 0, "countFailedByType": Object {}, + "countRunOutcomeByConnectorType": Object {}, "countTotal": 0, "errorMessage": "oh no", "hasErrors": true, diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.ts index 1e2320e2b1a5d..15d2d6f4d12e5 100644 --- a/x-pack/plugins/actions/server/usage/actions_telemetry.ts +++ b/x-pack/plugins/actions/server/usage/actions_telemetry.ts @@ -7,6 +7,11 @@ import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { ElasticsearchClient, Logger } from '@kbn/core/server'; +import { AggregationsTermsAggregateBase } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { + AvgActionRunOutcomeByConnectorTypeBucket, + parseActionRunOutcomeByConnectorTypesBucket, +} from './lib/parse_connector_type_bucket'; import { AlertHistoryEsIndexConnectorId } from '../../common'; import { ActionResult, PreConfiguredAction } from '../types'; @@ -395,7 +400,7 @@ export async function getInUseTotalCount( } } -function replaceFirstAndLastDotSymbols(strToReplace: string) { +export function replaceFirstAndLastDotSymbols(strToReplace: string) { const hasFirstSymbolDot = strToReplace.startsWith('.'); const appliedString = hasFirstSymbolDot ? strToReplace.replace('.', '__') : strToReplace; const hasLastSymbolDot = strToReplace.endsWith('.'); @@ -415,6 +420,7 @@ export async function getExecutionsPerDayCount( countFailedByType: Record; avgExecutionTime: number; avgExecutionTimeByType: Record; + countRunOutcomeByConnectorType: Record; }> { const scriptedMetric = { scripted_metric: { @@ -536,6 +542,35 @@ export async function getExecutionsPerDayCount( }, }, }, + count_connector_types_by_action_run_outcome_per_day: { + nested: { + path: 'kibana.saved_objects', + }, + aggs: { + actionSavedObjects: { + filter: { term: { 'kibana.saved_objects.type': 'action' } }, + aggs: { + connector_types: { + terms: { + field: 'kibana.saved_objects.type_id', + }, + aggs: { + outcome: { + reverse_nested: {}, + aggs: { + count: { + terms: { + field: 'event.outcome', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }, }, }); @@ -564,6 +599,14 @@ export async function getExecutionsPerDayCount( {} ); + const aggsCountConnectorTypeByActionRun = actionResults.aggregations as { + count_connector_types_by_action_run_outcome_per_day: { + actionSavedObjects: { + connector_types: AggregationsTermsAggregateBase; + }; + }; + }; + return { hasErrors: false, countTotal: aggsExecutions.total, @@ -586,6 +629,10 @@ export async function getExecutionsPerDayCount( ), avgExecutionTime: aggsAvgExecutionTime, avgExecutionTimeByType, + countRunOutcomeByConnectorType: parseActionRunOutcomeByConnectorTypesBucket( + aggsCountConnectorTypeByActionRun.count_connector_types_by_action_run_outcome_per_day + .actionSavedObjects.connector_types.buckets + ), }; } catch (err) { const errorMessage = err && err.message ? err.message : err.toString(); @@ -601,6 +648,7 @@ export async function getExecutionsPerDayCount( countFailedByType: {}, avgExecutionTime: 0, avgExecutionTimeByType: {}, + countRunOutcomeByConnectorType: {}, }; } } diff --git a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts index f6e02b2e0fec9..f49525a4eec05 100644 --- a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts +++ b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts @@ -47,6 +47,13 @@ export function createActionsUsageCollector( count_actions_executions_failed_by_type_per_day: byTypeSchema, avg_execution_time_per_day: { type: 'long' }, avg_execution_time_by_type_per_day: byTypeSchema, + count_connector_types_by_action_run_outcome_per_day: { + DYNAMIC_KEY: { + success: { type: 'long' }, + failure: { type: 'long' }, + unknown: { type: 'long' }, + }, + }, }, fetch: async () => { try { @@ -77,6 +84,7 @@ export function createActionsUsageCollector( count_actions_executions_failed_by_type_per_day: {}, avg_execution_time_per_day: 0, avg_execution_time_by_type_per_day: {}, + count_connector_types_by_action_run_outcome_per_day: {}, }; } }, diff --git a/x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.test.ts b/x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.test.ts new file mode 100644 index 0000000000000..1241cddfeb55e --- /dev/null +++ b/x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.test.ts @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { parseActionRunOutcomeByConnectorTypesBucket } from './parse_connector_type_bucket'; + +describe('parseActionRunOutcomeByConnectorTypesBucket', () => { + test('should correctly parse connector type bucket results', () => { + expect( + parseActionRunOutcomeByConnectorTypesBucket([ + { + key: '.server-log', + doc_count: 78, + outcome: { + count: { + buckets: [ + { key: 'success', doc_count: 2 }, + { key: 'failure', doc_count: 1 }, + ], + }, + }, + }, + { + key: '.index', + doc_count: 42, + outcome: { + count: { + buckets: [ + { key: 'success', doc_count: 3 }, + { key: 'failure', doc_count: 4 }, + ], + }, + }, + }, + ]) + ).toEqual({ + __index: { + failure: 4, + success: 3, + }, + '__server-log': { + failure: 1, + success: 2, + }, + }); + }); + + test('should handle missing values', () => { + expect( + parseActionRunOutcomeByConnectorTypesBucket([ + { + key: '.server-log', + doc_count: 78, + outcome: { + count: { + // @ts-expect-error + buckets: [{ key: 'success', doc_count: 2 }, { key: 'failure' }], + }, + }, + }, + { + key: '.index', + outcome: { + // @ts-expect-error + count: {}, + }, + }, + ]) + ).toEqual({ + '__server-log': { + failure: 0, + success: 2, + }, + __index: {}, + }); + }); + + test('should handle empty input', () => { + expect(parseActionRunOutcomeByConnectorTypesBucket([])).toEqual({}); + }); + // + test('should handle undefined input', () => { + expect(parseActionRunOutcomeByConnectorTypesBucket(undefined)).toEqual({}); + }); +}); diff --git a/x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.ts b/x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.ts new file mode 100644 index 0000000000000..96e1610c635d8 --- /dev/null +++ b/x-pack/plugins/actions/server/usage/lib/parse_connector_type_bucket.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AggregationsBuckets } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { replaceFirstAndLastDotSymbols } from '../actions_telemetry'; + +export interface AvgActionRunOutcomeByConnectorTypeBucket { + key: string; + doc_count: number; // Not used for duration telemetry but can be helpful later. + outcome: { count: { buckets: Array<{ key: string; doc_count: number }> } }; +} + +export function parseActionRunOutcomeByConnectorTypesBucket( + connectorTypeBuckets: AggregationsBuckets = [] +) { + const connectorTypes = connectorTypeBuckets as AvgActionRunOutcomeByConnectorTypeBucket[]; + return connectorTypes.reduce((acc, connectorType) => { + const outcomes = connectorType.outcome?.count?.buckets ?? []; + return { + ...acc, + [replaceFirstAndLastDotSymbols(connectorType.key)]: outcomes.reduce((accBucket, bucket) => { + return { ...accBucket, [replaceFirstAndLastDotSymbols(bucket.key)]: bucket.doc_count || 0 }; + }, {}), + }; + }, {}); +} diff --git a/x-pack/plugins/actions/server/usage/task.ts b/x-pack/plugins/actions/server/usage/task.ts index 15f70529d3852..e8861b30ae8b4 100644 --- a/x-pack/plugins/actions/server/usage/task.ts +++ b/x-pack/plugins/actions/server/usage/task.ts @@ -130,6 +130,8 @@ export function telemetryTaskRunner( totalExecutionsPerDay.countFailedByType, avg_execution_time_per_day: totalExecutionsPerDay.avgExecutionTime, avg_execution_time_by_type_per_day: totalExecutionsPerDay.avgExecutionTimeByType, + count_connector_types_by_action_run_outcome_per_day: + totalExecutionsPerDay.countRunOutcomeByConnectorType, }, runAt: getNextMidnight(), }; diff --git a/x-pack/plugins/actions/server/usage/types.ts b/x-pack/plugins/actions/server/usage/types.ts index b58ac9c096f63..62ee11af72f8f 100644 --- a/x-pack/plugins/actions/server/usage/types.ts +++ b/x-pack/plugins/actions/server/usage/types.ts @@ -22,6 +22,7 @@ export interface ActionsUsage { count_actions_executions_by_type_per_day: Record; count_actions_executions_failed_per_day: number; count_actions_executions_failed_by_type_per_day: Record; + count_connector_types_by_action_run_outcome_per_day: Record>; avg_execution_time_per_day: number; avg_execution_time_by_type_per_day: Record; } diff --git a/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts b/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts index 6e6eb3cb43f0d..5efd2d7a49152 100644 --- a/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts +++ b/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts @@ -116,6 +116,13 @@ const byStatusSchema: MakeSchemaFrom['count_rules_by_execution_st warning: { type: 'long' }, }; +const byStatusPerDaySchema: MakeSchemaFrom['count_rules_by_execution_status_per_day'] = + { + success: { type: 'long' }, + failure: { type: 'long' }, + unknown: { type: 'long' }, + }; + const byNotifyWhenSchema: MakeSchemaFrom['count_rules_by_notify_when'] = { on_action_group_change: { type: 'long' }, on_active_alert: { type: 'long' }, @@ -200,6 +207,7 @@ export function createAlertingUsageCollector( count_rules_muted: 0, count_rules_with_muted_alerts: 0, count_connector_types_by_consumers: {}, + count_rules_by_execution_status_per_day: {}, avg_execution_time_per_day: 0, avg_execution_time_by_type_per_day: {}, avg_es_search_duration_per_day: 0, @@ -283,6 +291,7 @@ export function createAlertingUsageCollector( count_rules_muted: { type: 'long' }, count_rules_with_muted_alerts: { type: 'long' }, count_connector_types_by_consumers: { DYNAMIC_KEY: { DYNAMIC_KEY: { type: 'long' } } }, + count_rules_by_execution_status_per_day: byStatusPerDaySchema, avg_execution_time_per_day: { type: 'long' }, avg_execution_time_by_type_per_day: byTypeSchema, avg_es_search_duration_per_day: { type: 'long' }, diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts index f3e21f6a161fa..64bc0ae8be0fb 100644 --- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts +++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts @@ -1291,6 +1291,14 @@ describe('event log telemetry', () => { avg_total_search_duration: { value: 28.630434782608695, }, + by_execution_status: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'success', doc_count: 21 }, + { key: 'failure', doc_count: 22 }, + ], + }, }, }); @@ -1377,7 +1385,6 @@ describe('event log telemetry', () => { logs__alert__document__count: 0, }, }, - alertsPercentilesByType: { p50: { '__index-threshold': 1, @@ -1398,6 +1405,10 @@ describe('event log telemetry', () => { logs__alert__document__count: 0, }, }, + countRulesByExecutionStatus: { + failure: 22, + success: 21, + }, hasErrors: false, }); }); @@ -1437,6 +1448,7 @@ describe('event log telemetry', () => { generatedActionsPercentilesByType: {}, alertsPercentiles: {}, alertsPercentilesByType: {}, + countRulesByExecutionStatus: {}, }); }); }); diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts index 703d579e66c25..e21df2376f4f8 100644 --- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts +++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts @@ -54,15 +54,14 @@ interface GetExecutionsPerDayCountResults { generatedActionsPercentilesByType: Record>; alertsPercentiles: Record; alertsPercentilesByType: Record>; + countRulesByExecutionStatus: Record; } - interface GetExecutionTimeoutsPerDayCountResults { hasErrors: boolean; errorMessage?: string; countExecutionTimeouts: number; countExecutionTimeoutsByType: Record; } - interface GetExecutionCountsExecutionFailures extends AggregationsSingleBucketAggregateBase { by_reason: AggregationsTermsAggregateBase; } @@ -145,6 +144,11 @@ export async function getExecutionsPerDayCount({ }, aggs: eventLogAggs, }, + by_execution_status: { + terms: { + field: 'event.outcome', + }, + }, }, }, }; @@ -165,6 +169,7 @@ export async function getExecutionsPerDayCount({ avg_execution_time: AggregationsSingleMetricAggregateBase; avg_es_search_duration: AggregationsSingleMetricAggregateBase; avg_total_search_duration: AggregationsSingleMetricAggregateBase; + by_execution_status: AggregationsTermsAggregateBase; }; const aggregationsByRuleTypeId: AggregationsBuckets = @@ -176,6 +181,9 @@ export async function getExecutionsPerDayCount({ ...parseExecutionFailureByRuleType(aggregationsByRuleTypeId), ...parseExecutionCountAggregationResults(aggregations), countTotalRuleExecutions: totalRuleExecutions ?? 0, + countRulesByExecutionStatus: parseSimpleRuleTypeBucket( + aggregations.by_execution_status.buckets + ), }; } catch (err) { const errorMessage = err && err.message ? err.message : err.toString(); @@ -204,6 +212,7 @@ export async function getExecutionsPerDayCount({ generatedActionsPercentilesByType: {}, alertsPercentiles: {}, alertsPercentilesByType: {}, + countRulesByExecutionStatus: {}, }; } } @@ -313,6 +322,14 @@ export async function getExecutionTimeoutsPerDayCount({ * avg_total_search_duration: { // average total search duration across executions * value: 43.74647887323944, * }, + * by_execution_status: { + * "doc_count_error_upper_bound":0, + * "sum_other_doc_count":0, + * "buckets":[ + * {"key":"success","doc_count":48}, + * {"key":"failure","doc_count":1} + * ] + * } * } */ diff --git a/x-pack/plugins/alerting/server/usage/task.ts b/x-pack/plugins/alerting/server/usage/task.ts index 4f835f3c4a64f..ab20844948011 100644 --- a/x-pack/plugins/alerting/server/usage/task.ts +++ b/x-pack/plugins/alerting/server/usage/task.ts @@ -161,6 +161,8 @@ export function telemetryTaskRunner( dailyExecutionCounts.countFailedExecutionsByReason, count_rules_executions_failured_by_reason_by_type_per_day: dailyExecutionCounts.countFailedExecutionsByReasonByType, + count_rules_by_execution_status_per_day: + dailyExecutionCounts.countRulesByExecutionStatus, count_rules_executions_timeouts_per_day: dailyExecutionTimeoutCounts.countExecutionTimeouts, count_rules_executions_timeouts_by_type_per_day: diff --git a/x-pack/plugins/alerting/server/usage/types.ts b/x-pack/plugins/alerting/server/usage/types.ts index 29a32de29bc1a..15c0f0a962710 100644 --- a/x-pack/plugins/alerting/server/usage/types.ts +++ b/x-pack/plugins/alerting/server/usage/types.ts @@ -42,6 +42,7 @@ export interface AlertingUsage { count_rules_snoozed: number; count_rules_muted: number; count_rules_with_muted_alerts: number; + count_rules_by_execution_status_per_day: Record; percentile_num_generated_actions_per_day: { p50: number; p90: number; diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index f5e06f58e8093..23f3a1dbd18c9 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -265,6 +265,23 @@ "type": "long" } } + }, + "count_connector_types_by_action_run_outcome_per_day": { + "properties": { + "DYNAMIC_KEY": { + "properties": { + "success": { + "type": "long" + }, + "failure": { + "type": "long" + }, + "unknown": { + "type": "long" + } + } + } + } } } }, @@ -1693,6 +1710,19 @@ } } }, + "count_rules_by_execution_status_per_day": { + "properties": { + "success": { + "type": "long" + }, + "failure": { + "type": "long" + }, + "unknown": { + "type": "long" + } + } + }, "avg_execution_time_per_day": { "type": "long" }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts index 7e6aec1347753..c89e5b48b236b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts @@ -246,6 +246,10 @@ export default function createAlertingAndActionsTelemetryTests({ getService }: F expect(telemetry.count_actions_executions_failed_by_type_per_day['test.throw'] > 0).to.be( true ); + + expect( + telemetry.count_connector_types_by_action_run_outcome_per_day['test.throw'].failure + ).to.greaterThan(0); } function verifyAlertingTelemetry(telemetry: any) { @@ -528,6 +532,9 @@ export default function createAlertingAndActionsTelemetryTests({ getService }: F // eslint-disable-next-line @typescript-eslint/naming-convention alertsFixture: { test__noop: 9, test__throw: 9, __slack: 3 }, }); + + expect(telemetry.count_rules_by_execution_status_per_day.failure).to.greaterThan(0); + expect(telemetry.count_rules_by_execution_status_per_day.success).to.greaterThan(0); } it('should retrieve telemetry data in the expected format', async () => { From 459b960d9d0dac747f22607ae8999f4f0f8c2f97 Mon Sep 17 00:00:00 2001 From: Kristof C Date: Tue, 20 Sep 2022 18:14:27 -0500 Subject: [PATCH 22/55] [Security Solution][4162] Add Alerts Widget to detail pages (#140150) * Add Alerts Widget to all detail pages * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * add tests * update tests and add local storage * update rulenames to navigate to rule page * Make LastUpdatedAt a common component as usage is across security_solution app * Update views and implementation to match new design spec * small cleanup * small fix fix for persistence * remove grow from from flexitems * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * Make changes from code review * Fix Filter button by wrapping it in a group * Make changes from Paul and Code review * update investigate in timeline button to use redux state * fix linting error Co-authored-by: Kristof-Pierre Cummings Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../alert_count_by_rule_by_status.test.tsx | 94 ++++++++ .../alert_count_by_rule_by_status.tsx | 192 +++++++++++++++++ .../alert_count_by_status/components/index.ts | 8 + .../multiselect_popover.test.tsx | 62 ++++++ .../multiselect_popover.tsx | 87 ++++++++ .../components/alert_count_by_status/index.ts | 8 + .../alert_count_by_status/mock_data.ts | 174 +++++++++++++++ .../alert_count_by_status/translations.ts | 46 ++++ .../use_alert_count_by_rule_by_status.test.ts | 131 ++++++++++++ .../use_alert_count_by_rule_by_status.ts | 202 ++++++++++++++++++ .../table/investigate_in_timeline_button.tsx | 18 +- .../components/last_updated_at/index.ts | 8 + .../last_updated_at/last_updated_at.test.tsx | 33 +++ .../last_updated_at/last_updated_at.tsx | 38 ++++ .../detection_engine/alerts/constants.ts | 4 +- .../public/hosts/pages/details/index.tsx | 76 ++++--- .../public/network/pages/details/index.tsx | 38 +++- .../alerts_by_status/alerts_by_status.tsx | 63 +++--- .../alerts_by_status/use_alerts_by_status.ts | 34 ++- .../cases_by_status/cases_by_status.tsx | 2 +- .../cases_table/cases_table.tsx | 2 +- .../hooks/use_navigate_to_timeline.tsx | 44 +++- .../host_alerts_table/host_alerts_table.tsx | 3 +- .../rule_alerts_table/rule_alerts_table.tsx | 7 +- .../soc_trends/soc_trends.tsx | 2 +- .../detection_response/translations.ts | 7 + .../user_alerts_table/user_alerts_table.tsx | 3 +- .../components/detection_response/utils.tsx | 29 --- .../entity_analytics/anomalies/index.tsx | 2 +- .../host_risk_score/index.tsx | 2 +- .../user_risk_score/index.tsx | 2 +- .../public/users/pages/details/index.tsx | 52 ++++- 32 files changed, 1357 insertions(+), 116 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/index.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/index.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/mock_data.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/translations.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/last_updated_at/index.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/last_updated_at/last_updated_at.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/last_updated_at/last_updated_at.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.test.tsx b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.test.tsx new file mode 100644 index 0000000000000..df001ccf70ca9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.test.tsx @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { render } from '@testing-library/react'; + +import { TestProviders } from '../../mock'; +import { AlertCountByRuleByStatus } from './alert_count_by_rule_by_status'; +import { COLUMN_HEADER_COUNT, COLUMN_HEADER_RULE_NAME } from './translations'; +import type { UseAlertCountByRuleByStatus } from './use_alert_count_by_rule_by_status'; + +type UseAlertCountByRuleByStatusReturn = ReturnType; +const defaultUseAlertCountByRuleByStatusReturn: UseAlertCountByRuleByStatusReturn = { + items: [], + isLoading: false, + updatedAt: Date.now(), +}; + +const mockUseAlertCountByRuleByStatus = jest.fn(() => defaultUseAlertCountByRuleByStatusReturn); +const mockUseAlertCountByRuleByStatusReturn = ( + overrides: Partial +) => { + mockUseAlertCountByRuleByStatus.mockReturnValue({ + ...defaultUseAlertCountByRuleByStatusReturn, + ...overrides, + }); +}; + +jest.mock('./use_alert_count_by_rule_by_status', () => ({ + useAlertCountByRuleByStatus: () => mockUseAlertCountByRuleByStatus(), +})); + +const renderComponent = () => + render( + + + + ); + +describe('AlertCountByRuleByStatus', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render empty table', () => { + const { getByText, queryByTestId } = renderComponent(); + + expect(queryByTestId('alertCountByRulePanel')).toBeInTheDocument(); + expect(getByText('No alerts to display')).toBeInTheDocument(); + }); + + it('should render a loading table', () => { + mockUseAlertCountByRuleByStatusReturn({ isLoading: true }); + const { getByText, queryByTestId } = renderComponent(); + + expect(getByText('Updating...')).toBeInTheDocument(); + expect(queryByTestId('alertCountByRuleTable')).toHaveClass('euiBasicTable-loading'); + }); + + it('should render the table columns', () => { + const { getAllByRole } = renderComponent(); + const columnHeaders = getAllByRole('columnheader'); + + expect(columnHeaders.at(0)).toHaveTextContent(COLUMN_HEADER_RULE_NAME); + expect(columnHeaders.at(1)).toHaveTextContent(COLUMN_HEADER_COUNT); + }); + + it('should render the table items', () => { + mockUseAlertCountByRuleByStatusReturn({ items: mockItem }); + const { queryByTestId } = renderComponent(); + + expect(queryByTestId(COLUMN_HEADER_RULE_NAME)).toHaveTextContent('Test Name'); + expect(queryByTestId(COLUMN_HEADER_COUNT)).toHaveTextContent('100'); + }); +}); + +const mockItem = [ + { + count: 100, + ruleName: 'Test Name', + uuid: 'uuid', + }, +]; diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.tsx b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.tsx new file mode 100644 index 0000000000000..2da871fdab83f --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/alert_count_by_rule_by_status.tsx @@ -0,0 +1,192 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; + +import type { EuiBasicTableColumn } from '@elastic/eui'; +import { EuiBasicTable, EuiEmptyPrompt, EuiLink, EuiPanel, EuiToolTip } from '@elastic/eui'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; + +import type { Status } from '../../../../common/detection_engine/schemas/common'; +import { SecurityPageName } from '../../../../common/constants'; +import { useNavigateToTimeline } from '../../../overview/components/detection_response/hooks/use_navigate_to_timeline'; +import { useQueryToggle } from '../../containers/query_toggle'; +import { FormattedCount } from '../formatted_number'; +import { HeaderSection } from '../header_section'; +import { HoverVisibilityContainer } from '../hover_visibility_container'; +import { BUTTON_CLASS as INSPECT_BUTTON_CLASS } from '../inspect'; +import { LastUpdatedAt } from '../last_updated_at'; +import { SecuritySolutionLinkAnchor } from '../links'; +import { useLocalStorage } from '../local_storage'; +import { MultiSelectPopover } from './components'; +import * as i18n from './translations'; +import type { AlertCountByRuleByStatusItem } from './use_alert_count_by_rule_by_status'; +import { useAlertCountByRuleByStatus } from './use_alert_count_by_rule_by_status'; + +interface EntityFilter { + field: string; + value: string; +} +interface AlertCountByStatusProps { + entityFilter: EntityFilter; + signalIndexName: string | null; +} + +interface StatusSelection { + [fieldName: string]: Status[]; +} + +type GetTableColumns = ( + openRuleInTimelineWithAdditionalFields: (ruleName: string) => void +) => Array>; + +const KIBANA_RULE_ALERT_FIELD = 'kibana.alert.rule.name'; +const STATUSES = ['open', 'acknowledged', 'closed'] as const; +const ALERT_COUNT_BY_RULE_BY_STATUS = 'alerts-by-status-by-rule'; +const LOCAL_STORAGE_KEY = 'alertCountByFieldNameWidgetSettings'; + +const StyledEuiPanel = euiStyled(EuiPanel)` + display: flex; + flex-direction: column; + position: relative; + overflow: hidden; + max-height: 308px; +`; + +export const AlertCountByRuleByStatus = React.memo( + ({ entityFilter, signalIndexName }: AlertCountByStatusProps) => { + const { field, value } = entityFilter; + + const queryId = `${ALERT_COUNT_BY_RULE_BY_STATUS}-by-${field}`; + const { toggleStatus, setToggleStatus } = useQueryToggle(queryId); + + const { openEntityInTimeline } = useNavigateToTimeline(); + + const columns = useMemo( + () => + getTableColumns((ruleName: string) => + openEntityInTimeline([{ field: KIBANA_RULE_ALERT_FIELD, value: ruleName }, entityFilter]) + ), + [entityFilter, openEntityInTimeline] + ); + + const [selectedStatusesByField, setSelectedStatusesByField] = useLocalStorage({ + defaultValue: { + [field]: ['open'], + }, + key: LOCAL_STORAGE_KEY, + isInvalidDefault: (valueFromStorage) => { + return !valueFromStorage; + }, + }); + + const updateSelection = useCallback( + (selection: Status[]) => { + setSelectedStatusesByField({ + ...selectedStatusesByField, + [field]: selection, + }); + }, + [field, selectedStatusesByField, setSelectedStatusesByField] + ); + + const { items, isLoading, updatedAt } = useAlertCountByRuleByStatus({ + field, + value, + queryId, + statuses: selectedStatusesByField[field] as Status[], + skip: !toggleStatus, + signalIndexName, + }); + + return ( + + + <> + } + > + + updateSelection(selectedItems as Status[]) + } + /> + + + {toggleStatus && ( + <> + {i18n.NO_ALERTS_FOUND}} titleSize="xs" /> + } + /> + + )} + + + + ); + } +); + +AlertCountByRuleByStatus.displayName = 'AlertCountByStatus'; + +export const getTableColumns: GetTableColumns = (openRuleInTimelineWithAdditionalFields) => [ + { + field: 'ruleName', + name: i18n.COLUMN_HEADER_RULE_NAME, + 'data-test-subj': i18n.COLUMN_HEADER_RULE_NAME, + align: 'left', + width: '67%', + sortable: false, + render: (ruleName: string, { uuid }) => ( + + + {ruleName} + + + ), + }, + { + field: 'count', + name: i18n.COLUMN_HEADER_COUNT, + width: '33%', + 'data-test-subj': i18n.COLUMN_HEADER_COUNT, + sortable: true, + align: 'right', + render: (count: number, { ruleName }) => ( + openRuleInTimelineWithAdditionalFields(ruleName)} + > + + + ), + }, +]; diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/index.ts b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/index.ts new file mode 100644 index 0000000000000..5897499d5b6ee --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { MultiSelectPopover } from './multiselect_popover/multiselect_popover'; diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.test.tsx b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.test.tsx new file mode 100644 index 0000000000000..019b8080a9ed3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.test.tsx @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { fireEvent, render } from '@testing-library/react'; + +import type { MultiSelectPopoverProps } from './multiselect_popover'; +import { MultiSelectPopover } from './multiselect_popover'; + +const mockSelectedItemsChange = jest.fn(); + +const defaultProps = { + title: 'title', + allItems: ['a', 'b', 'c'], + selectedItems: [], + onSelectedItemsChange: mockSelectedItemsChange, +}; + +const renderComponent = (overrides?: Partial) => + render(); + +describe('MultiSelectPopOver', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders all items', () => { + const { getByText, getByTestId } = renderComponent(); + fireEvent.click(getByTestId('multiselect-popover-button')); + + expect(getByText('title')).toBeInTheDocument(); + expect(getByText('a')).toBeInTheDocument(); + expect(getByText('b')).toBeInTheDocument(); + expect(getByText('c')).toBeInTheDocument(); + }); + + it('calls onSelectedItemdChange when item is clicked', () => { + const { getByText, getByTestId } = renderComponent(); + + fireEvent.click(getByTestId('multiselect-popover-button')); + fireEvent.click(getByText('a')); + + expect(mockSelectedItemsChange).toHaveBeenCalledWith(['a']); + }); + + it('shows selected items as selected', () => { + const { getByText, getByTestId } = renderComponent({ selectedItems: ['a'] }); + fireEvent.click(getByTestId('multiselect-popover-button')); + + // confirm there is a 'check mark' next to the selected item + expect(getByText('a').parentElement?.firstChild?.firstChild).toHaveAttribute( + 'data-euiicon-type', + 'check' + ); + expect(getByText('1')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.tsx b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.tsx new file mode 100644 index 0000000000000..ad6d9fa9961b2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/components/multiselect_popover/multiselect_popover.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo, useState } from 'react'; + +import { EuiFilterButton, EuiFilterGroup, EuiFilterSelectItem, EuiPopover } from '@elastic/eui'; +export interface MultiSelectPopoverProps { + title: string; + allItems: readonly string[]; + selectedItems: string[]; + onSelectedItemsChange: (newItems: string[]) => void; +} + +export const MultiSelectPopover = React.memo( + ({ allItems, selectedItems, title, onSelectedItemsChange }: MultiSelectPopoverProps) => { + const [isItemPopoverOpen, setIsItemPopoverOpen] = useState(false); + + const onChange = useCallback( + (item: string) => onSelectedItemsChange(getUpdatedSelectedItems(item, selectedItems)), + [selectedItems, onSelectedItemsChange] + ); + + const itemList = useMemo(() => { + return allItems.map((item, index) => ( + onChange(item)} + title={item} + > + {item} + + )); + }, [allItems, selectedItems, onChange]); + + const togglePopover = useCallback( + (toState?: boolean) => { + setIsItemPopoverOpen((s) => (toState ? toState : !s)); + }, + [setIsItemPopoverOpen] + ); + + return ( + + togglePopover()} + numFilters={allItems.length} + isSelected={isItemPopoverOpen} + hasActiveFilters={selectedItems.length > 0} + numActiveFilters={selectedItems.length} + > + {title} + + + } + isOpen={isItemPopoverOpen} + closePopover={() => togglePopover(false)} + panelPaddingSize="none" + > + {itemList} + + ); + } +); + +MultiSelectPopover.displayName = 'MultiSelectPopover'; + +const getUpdatedSelectedItems = (item: string, selectedItems: string[]): string[] => { + const selectedGroupIndex = selectedItems.indexOf(item); + const updatedSelectedItems = [...selectedItems]; + if (selectedGroupIndex >= 0) { + updatedSelectedItems.splice(selectedGroupIndex, 1); + } else { + updatedSelectedItems.push(item); + } + return updatedSelectedItems; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/index.ts b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/index.ts new file mode 100644 index 0000000000000..ef21c6282e0ba --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { AlertCountByRuleByStatus } from './alert_count_by_rule_by_status'; diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/mock_data.ts b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/mock_data.ts new file mode 100644 index 0000000000000..85cd90cc5226e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/mock_data.ts @@ -0,0 +1,174 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ALERTS_QUERY_NAMES } from '../../../detections/containers/detection_engine/alerts/constants'; +import { buildRuleAlertsByEntityQuery } from './use_alert_count_by_rule_by_status'; + +export const mockAlertCountByRuleResult = { + aggregations: { + alertsByRuleAggregation: { + buckets: [ + { + key: 'Critical', + doc_count: 1, + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': '100', + }, + }, + ], + }, + }, + }, + { + key: 'High', + doc_count: 1, + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': '200', + }, + }, + ], + }, + }, + }, + { + key: 'Medium', + doc_count: 1, + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': '300', + }, + }, + ], + }, + }, + }, + { + key: 'another rule', + doc_count: 1, + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': '400', + }, + }, + ], + }, + }, + }, + { + key: 'bad users!!', + doc_count: 1, + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': '500', + }, + }, + ], + }, + }, + }, + { + key: 'endpoint', + doc_count: 1, + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': '600', + }, + }, + ], + }, + }, + }, + { + key: 'low', + doc_count: 1, + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': '700', + }, + }, + ], + }, + }, + }, + ], + }, + }, +}; + +export const parsedAlertCountByRuleResult = [ + { + ruleName: 'Critical', + count: 1, + uuid: '100', + }, + { + ruleName: 'High', + count: 1, + uuid: '200', + }, + { + ruleName: 'Medium', + count: 1, + uuid: '300', + }, + { + ruleName: 'another rule', + count: 1, + uuid: '400', + }, + { + ruleName: 'bad users!!', + count: 1, + uuid: '500', + }, + { + ruleName: 'endpoint', + count: 1, + uuid: '600', + }, + { + ruleName: 'low', + count: 1, + uuid: '700', + }, +]; + +export const mockQuery = () => ({ + query: buildRuleAlertsByEntityQuery({ + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', + statuses: ['open'], + field: 'test_field', + value: 'test_value', + }), + indexName: 'signalIndexName', + skip: false, + queryName: ALERTS_QUERY_NAMES.ALERTS_COUNT_BY_STATUS, +}); diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/translations.ts b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/translations.ts new file mode 100644 index 0000000000000..e95673993353e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/translations.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const Status = i18n.translate('xpack.securitySolution.alertCountByRuleByStatus.status', { + defaultMessage: 'Status', +}); + +export const ALERTS_BY_RULE = i18n.translate( + 'xpack.securitySolution.alertCountByRuleByStatus.alertsByRule', + { + defaultMessage: 'Alerts by Rule', + } +); +export const COLUMN_HEADER_RULE_NAME = i18n.translate( + 'xpack.securitySolution.alertCountByRuleByStatus.ruleName', + { + defaultMessage: 'kibana.alert.rule.name', + } +); + +export const COLUMN_HEADER_COUNT = i18n.translate( + 'xpack.securitySolution.alertCountByRuleByStatus.count', + { + defaultMessage: 'count', + } +); + +export const TOOLTIP_TITLE = i18n.translate( + 'xpack.securitySolution.alertCountByRuleByStatus.tooltipTitle', + { + defaultMessage: 'Rule name', + } +); + +export const NO_ALERTS_FOUND = i18n.translate( + 'xpack.securitySolution.alertCountByRuleByStatus.noRuleAlerts', + { + defaultMessage: 'No alerts to display', + } +); diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.test.ts b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.test.ts new file mode 100644 index 0000000000000..4caf3bf6c04db --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.test.ts @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; + +import { mockQuery, mockAlertCountByRuleResult, parsedAlertCountByRuleResult } from './mock_data'; +import type { + UseAlertCountByRuleByStatus, + UseAlertCountByRuleByStatusProps, +} from './use_alert_count_by_rule_by_status'; +import { useAlertCountByRuleByStatus } from './use_alert_count_by_rule_by_status'; + +const dateNow = new Date('2022-04-15T12:00:00.000Z').valueOf(); +const mockDateNow = jest.fn().mockReturnValue(dateNow); +Date.now = jest.fn(() => mockDateNow()) as unknown as DateConstructor['now']; + +const defaultUseQueryAlertsReturn = { + loading: false, + data: null, + setQuery: () => {}, + response: '', + request: '', + refetch: () => {}, +}; + +const mockUseQueryAlerts = jest.fn().mockReturnValue(defaultUseQueryAlertsReturn); +jest.mock('../../../detections/containers/detection_engine/alerts/use_query', () => { + return { + useQueryAlerts: (...props: unknown[]) => mockUseQueryAlerts(...props), + }; +}); + +const from = '2020-07-07T08:20:18.966Z'; +const to = '2020-07-08T08:20:18.966Z'; + +const mockUseGlobalTime = jest + .fn() + .mockReturnValue({ from, to, setQuery: jest.fn(), deleteQuery: jest.fn() }); +jest.mock('../../containers/use_global_time', () => { + return { + useGlobalTime: (...props: unknown[]) => mockUseGlobalTime(...props), + }; +}); + +jest.mock('../../../detections/containers/detection_engine/alerts/use_signal_index', () => ({ + useSignalIndex: () => ({ signalIndexName: 'signalIndexName' }), +})); + +const renderUseAlertCountByRuleByStatus = ( + overrides: Partial = {} +) => + renderHook>(() => + useAlertCountByRuleByStatus({ + skip: false, + field: 'test_field', + value: 'test_value', + statuses: ['open'], + queryId: 'queryId', + signalIndexName: 'signalIndexName', + ...overrides, + }) + ); + +describe('useAlertCountByRuleByStatus', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockDateNow.mockReturnValue(dateNow); + mockUseQueryAlerts.mockReturnValue(defaultUseQueryAlertsReturn); + }); + + it('should return default values', () => { + const { result } = renderUseAlertCountByRuleByStatus(); + + expect(result.current).toEqual({ + items: [], + isLoading: false, + updatedAt: dateNow, + }); + + expect(mockUseQueryAlerts).toBeCalledWith(mockQuery()); + }); + + it('should return parsed items', () => { + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockAlertCountByRuleResult, + }); + + const { result } = renderUseAlertCountByRuleByStatus(); + + expect(result.current).toEqual({ + items: parsedAlertCountByRuleResult, + isLoading: false, + updatedAt: dateNow, + }); + }); + + it('should return new updatedAt', () => { + const newDateNow = new Date('2022-04-08T14:00:00.000Z').valueOf(); + mockDateNow.mockReturnValue(newDateNow); + mockDateNow.mockReturnValueOnce(dateNow); + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockAlertCountByRuleResult, + }); + + const { result } = renderUseAlertCountByRuleByStatus(); + expect(mockDateNow).toHaveBeenCalled(); + expect(result.current).toEqual({ + items: parsedAlertCountByRuleResult, + isLoading: false, + updatedAt: newDateNow, + }); + }); + + it('should skip the query', () => { + const { result } = renderUseAlertCountByRuleByStatus({ skip: true }); + + expect(mockUseQueryAlerts).toBeCalledWith({ ...mockQuery(), skip: true }); + + expect(result.current).toEqual({ + items: [], + isLoading: false, + updatedAt: dateNow, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.ts b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.ts new file mode 100644 index 0000000000000..b59862bf0d6ee --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alert_count_by_status/use_alert_count_by_rule_by_status.ts @@ -0,0 +1,202 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useEffect, useState } from 'react'; + +import type { Status } from '../../../../common/detection_engine/schemas/common'; +import type { GenericBuckets } from '../../../../common/search_strategy'; +import { ALERTS_QUERY_NAMES } from '../../../detections/containers/detection_engine/alerts/constants'; +import { useQueryAlerts } from '../../../detections/containers/detection_engine/alerts/use_query'; +import { useGlobalTime } from '../../containers/use_global_time'; +import { useQueryInspector } from '../page/manage_query'; + +export interface AlertCountByRuleByStatusItem { + ruleName: string; + count: number; + uuid: string; +} + +export interface UseAlertCountByRuleByStatusProps { + field: string; + value: string; + queryId: string; + statuses: Status[]; + skip?: boolean; + signalIndexName: string | null; +} +export type UseAlertCountByRuleByStatus = (props: UseAlertCountByRuleByStatusProps) => { + items: AlertCountByRuleByStatusItem[]; + isLoading: boolean; + updatedAt: number; +}; + +const ALERTS_BY_RULE_AGG = 'alertsByRuleAggregation'; + +export const useAlertCountByRuleByStatus: UseAlertCountByRuleByStatus = ({ + field, + value, + queryId, + statuses, + skip = false, + signalIndexName, +}) => { + const [updatedAt, setUpdatedAt] = useState(Date.now()); + const [items, setItems] = useState([]); + + const { to, from, deleteQuery, setQuery } = useGlobalTime(); + + const { + loading: isLoading, + data, + setQuery: setAlertsQuery, + response, + request, + refetch: refetchQuery, + } = useQueryAlerts({ + query: buildRuleAlertsByEntityQuery({ + from, + to, + field, + value, + statuses, + }), + skip, + queryName: ALERTS_QUERY_NAMES.ALERTS_COUNT_BY_STATUS, + indexName: signalIndexName, + }); + + useEffect(() => { + setAlertsQuery( + buildRuleAlertsByEntityQuery({ + from, + to, + field, + value, + statuses, + }) + ); + }, [setAlertsQuery, from, to, field, value, statuses]); + + useEffect(() => { + if (!data) { + setItems([]); + } else { + setItems(parseAlertCountByRuleItems(data.aggregations as AlertCountByRuleByFieldAggregation)); + } + setUpdatedAt(Date.now()); + }, [data]); + + const refetch = useCallback(() => { + if (!skip && refetchQuery) { + refetchQuery(); + } + }, [skip, refetchQuery]); + + useQueryInspector({ + deleteQuery, + inspect: { + dsl: [request], + response: [response], + }, + refetch, + setQuery, + queryId, + loading: isLoading, + }); + + return { items, isLoading, updatedAt }; +}; + +export const buildRuleAlertsByEntityQuery = ({ + from, + to, + field, + value, + statuses, +}: { + from: string; + to: string; + statuses: string[]; + field: string; + value: string; +}) => ({ + size: 0, + query: { + bool: { + filter: [ + { + range: { + '@timestamp': { + gte: from, + lte: to, + }, + }, + }, + { + terms: { + 'kibana.alert.workflow_status': statuses, + }, + }, + { + term: { + [field]: value, + }, + }, + ], + }, + }, + aggs: { + [ALERTS_BY_RULE_AGG]: { + terms: { + field: 'kibana.alert.rule.name', + size: 100, + }, + aggs: { + ruleUuid: { + top_hits: { + _source: ['kibana.alert.rule.uuid'], + size: 1, + }, + }, + }, + }, + }, +}); + +interface RuleUuidData extends GenericBuckets { + ruleUuid: { + hits: { + hits: [ + { + _source: { + 'kibana.alert.rule.uuid': string; + }; + } + ]; + }; + }; +} + +interface AlertCountByRuleByFieldAggregation { + [ALERTS_BY_RULE_AGG]: { + buckets: RuleUuidData[]; + }; +} + +const parseAlertCountByRuleItems = ( + aggregations?: AlertCountByRuleByFieldAggregation +): AlertCountByRuleByStatusItem[] => { + const buckets = aggregations?.[ALERTS_BY_RULE_AGG].buckets ?? []; + return buckets.map((bucket) => { + const uuid = bucket.ruleUuid.hits?.hits[0]?._source['kibana.alert.rule.uuid'] || ''; + return { + ruleName: bucket.key, + count: bucket.doc_count, + uuid, + }; + }); +}; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx index ca30250136f45..b1819128a14a8 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/table/investigate_in_timeline_button.tsx @@ -5,10 +5,11 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EuiButton, EuiButtonEmpty } from '@elastic/eui'; import { useDispatch } from 'react-redux'; +import { sourcererSelectors } from '../../../store'; import { InputsModelId } from '../../../store/inputs/constants'; import { inputsActions } from '../../../store/inputs'; import { updateProviders } from '../../../../timelines/store/timeline/actions'; @@ -18,6 +19,7 @@ import type { DataProvider } from '../../../../../common/types'; import { TimelineId, TimelineType } from '../../../../../common/types/timeline'; import { useCreateTimeline } from '../../../../timelines/components/timeline/properties/use_create_timeline'; import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../../detections/components/alerts_table/translations'; +import { useDeepEqualSelector } from '../../../hooks/use_selector'; export const InvestigateInTimelineButton: React.FunctionComponent<{ asEmptyButton: boolean; @@ -25,6 +27,14 @@ export const InvestigateInTimelineButton: React.FunctionComponent<{ }> = ({ asEmptyButton, children, dataProviders, ...rest }) => { const dispatch = useDispatch(); + const getDataViewsSelector = useMemo( + () => sourcererSelectors.getSourcererDataViewsSelector(), + [] + ); + const { defaultDataView, signalIndexName } = useDeepEqualSelector((state) => + getDataViewsSelector(state) + ); + const clearTimeline = useCreateTimeline({ timelineId: TimelineId.active, timelineType: TimelineType.default, @@ -46,14 +56,14 @@ export const InvestigateInTimelineButton: React.FunctionComponent<{ dispatch( sourcererActions.setSelectedDataView({ id: SourcererScopeName.timeline, - selectedDataViewId: 'security-solution-default', - selectedPatterns: ['.alerts-security.alerts-default'], + selectedDataViewId: defaultDataView.id, + selectedPatterns: [signalIndexName || ''], }) ); // Unlock the time range from the global time range dispatch(inputsActions.removeLinkTo([InputsModelId.timeline, InputsModelId.global])); } - }, [dispatch, clearTimeline, dataProviders]); + }, [dataProviders, clearTimeline, dispatch, defaultDataView.id, signalIndexName]); return asEmptyButton ? ( { + it('Should show "updating" text while loading', () => { + const { getByText } = render(); + + expect(getByText('Updating...')).toBeInTheDocument(); + expect(() => getByText(/Updated/)).toThrow(); + }); + + it('should render "updated" text when loaded', () => { + const { getByText } = render( + + + + ); + + expect(getByText(/Updated/)).toBeInTheDocument(); + expect(() => getByText('Updating...')).toThrow(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/last_updated_at/last_updated_at.tsx b/x-pack/plugins/security_solution/public/common/components/last_updated_at/last_updated_at.tsx new file mode 100644 index 0000000000000..a596d3f0b2a3b --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/last_updated_at/last_updated_at.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedRelative } from '@kbn/i18n-react'; + +interface LastUpdatedAtProps { + updatedAt: number; + isUpdating: boolean; +} + +const UPDATING = i18n.translate('xpack.securitySolution.detectionResponse.updating', { + defaultMessage: 'Updating...', +}); + +const UPDATED = i18n.translate('xpack.securitySolution.detectionResponse.updated', { + defaultMessage: 'Updated', +}); + +export const LastUpdatedAt: React.FC = ({ isUpdating, updatedAt }) => ( + + {isUpdating ? ( + {UPDATING} + ) : ( + + <>{UPDATED} + + + )} + +); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/constants.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/constants.ts index 5bd4206761219..a6dcf82dd4071 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/constants.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/constants.ts @@ -9,7 +9,9 @@ import { APP_UI_ID } from '../../../../../common/constants'; export const ALERTS_QUERY_NAMES = { ADD_EXCEPTION_FLYOUT: `${APP_UI_ID} fetchAlerts addExceptionFlyout`, + ALERTS_COUNT_BY_STATUS: `${APP_UI_ID} fetchAlerts byRulebyCount`, BY_ID: `${APP_UI_ID} fetchAlerts byId`, + BY_RULE_BY_STATUS: `${APP_UI_ID} fetchAlerts byRulebyStatus`, BY_RULE_ID: `${APP_UI_ID} fetchAlerts byRuleId`, BY_SEVERITY: `${APP_UI_ID} fetchAlerts bySeverity`, BY_STATUS: `${APP_UI_ID} fetchAlerts byStatus`, @@ -17,8 +19,8 @@ export const ALERTS_QUERY_NAMES = { COUNT: `${APP_UI_ID} fetchAlerts count`, HISTOGRAM: `${APP_UI_ID} fetchAlerts histogram`, PREVALENCE: `${APP_UI_ID} fetchAlerts prevalence`, + SOC_TRENDS: `${APP_UI_ID} fetchAlerts socTrends`, TREE_MAP: `${APP_UI_ID} fetchAlerts treeMap`, VULNERABLE_HOSTS: `${APP_UI_ID} fetchAlerts vulnerableHosts`, VULNERABLE_USERS: `${APP_UI_ID} fetchAlerts vulnerableUsers`, - SOC_TRENDS: `${APP_UI_ID} fetchAlerts socTrends`, } as const; diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx index 7bac79b20a821..fb39b402c84d2 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx @@ -5,18 +5,27 @@ * 2.0. */ -import { EuiHorizontalRule, EuiSpacer, EuiWindowEvent } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiSpacer, + EuiWindowEvent, +} from '@elastic/eui'; import { noop } from 'lodash/fp'; import React, { useEffect, useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import type { Filter } from '@kbn/es-query'; import { getEsQueryConfig } from '@kbn/data-plugin/common'; + +import { AlertsByStatus } from '../../../overview/components/detection_response/alerts_by_status'; +import { useSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_signal_index'; +import { useAlertsPrivileges } from '../../../detections/containers/detection_engine/alerts/use_alerts_privileges'; import { InputsModelId } from '../../../common/store/inputs/constants'; import type { HostItem } from '../../../../common/search_strategy'; import { LastEventIndexKey } from '../../../../common/search_strategy'; import { SecurityPageName } from '../../../app/types'; -import type { UpdateDateRange } from '../../../common/components/charts/common'; import { FiltersGlobal } from '../../../common/components/filters_global'; import { HeaderPage } from '../../../common/components/header_page'; import { LastEventTime } from '../../../common/components/last_event_time'; @@ -26,7 +35,6 @@ import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { scoreIntervalToDateTime } from '../../../common/components/ml/score/score_interval_to_datetime'; import { SecuritySolutionTabNavigation } from '../../../common/components/navigation'; -import { HostsDetailsKpiComponent } from '../../components/kpi_hosts'; import { HostOverview } from '../../../overview/components/host_overview'; import { SiemSearchBar } from '../../../common/components/search_bar'; import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; @@ -55,8 +63,10 @@ import { manageQuery } from '../../../common/components/page/manage_query'; import { useInvalidFilterQuery } from '../../../common/hooks/use_invalid_filter_query'; import { useSourcererDataView } from '../../../common/containers/sourcerer'; import { LandingPageComponent } from '../../../common/components/landing_page'; +import { AlertCountByRuleByStatus } from '../../../common/components/alert_count_by_status'; import { useLicense } from '../../../common/hooks/use_license'; +const ES_HOST_FIELD = 'host.hostname'; const HostOverviewManage = manageQuery(HostOverview); const HostDetailsComponent: React.FC = ({ detailName, hostDetailsPagePath }) => { @@ -75,6 +85,7 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta const { to, from, deleteQuery, setQuery, isInitializing } = useGlobalTime(); const { globalFullScreen } = useGlobalFullScreen(); + const { signalIndexName } = useSignalIndex(); const capabilities = useMlCapabilities(); const kibana = useKibana(); @@ -86,22 +97,6 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta const isEnterprisePlus = useLicense().isEnterprise(); - const updateDateRange = useCallback( - ({ x }) => { - if (!x) { - return; - } - const [min, max] = x; - dispatch( - setAbsoluteRangeDatePicker({ - id: InputsModelId.global, - from: new Date(min).toISOString(), - to: new Date(max).toISOString(), - }) - ); - }, - [dispatch] - ); const narrowDateRange = useCallback( (score, interval) => { const fromTo = scoreIntervalToDateTime(score, interval); @@ -139,6 +134,17 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta const isPlatinumOrTrialLicense = useMlCapabilities().isPlatinumOrTrialLicense; + const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const canReadAlerts = hasKibanaREAD && hasIndexRead; + + const entityFilter = useMemo( + () => ({ + field: ES_HOST_FIELD, + value: detailName, + }), + [detailName] + ); + return ( <> {indicesExist ? ( @@ -190,21 +196,29 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta /> )} - - - - + {canReadAlerts && ( + <> + + + + + + + + + + + )} + { [] ); + const { signalIndexName } = useSignalIndex(); + const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const canReadAlerts = hasKibanaREAD && hasIndexRead; + const query = useDeepEqualSelector(getGlobalQuerySelector); const filters = useDeepEqualSelector(getGlobalFiltersQuerySelector); @@ -137,6 +145,14 @@ const NetworkDetailsComponent: React.FC = () => { [isInitializing, filterQuery] ); + const entityFilter = useMemo( + () => ({ + field: `${flowTarget}.ip`, + value: detailName, + }), + [detailName, flowTarget] + ); + return (
{indicesExist ? ( @@ -161,6 +177,7 @@ const NetworkDetailsComponent: React.FC = () => { > + { narrowDateRange={narrowDateRange} indexPatterns={selectedPatterns} /> + + + {canReadAlerts && ( + <> + + + + + + + + + + + )} + diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx index 7bb8948825aae..0e348b123c3c0 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx @@ -5,7 +5,16 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiProgress, EuiSpacer, EuiText } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiProgress, + EuiSpacer, + EuiText, + useIsWithinMaxBreakpoint, + useIsWithinMinBreakpoint, +} from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import type { ShapeTreeNode } from '@elastic/charts'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; @@ -13,15 +22,16 @@ import styled from 'styled-components'; import type { FillColor } from '../../../../common/components/charts/donutchart'; import { DonutChart } from '../../../../common/components/charts/donutchart'; import { SecurityPageName } from '../../../../../common/constants'; -import { useNavigation } from '../../../../common/lib/kibana'; import { HeaderSection } from '../../../../common/components/header_section'; import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; import type { LegendItem } from '../../../../common/components/charts/legend_item'; +import type { EntityFilter } from './use_alerts_by_status'; import { useAlertsByStatus } from './use_alerts_by_status'; import { ALERTS, ALERTS_TEXT, + ALERTS_BY_STATUS_TEXT, STATUS_ACKNOWLEDGED, STATUS_CLOSED, STATUS_CRITICAL_LABEL, @@ -31,16 +41,16 @@ import { STATUS_OPEN, } from '../translations'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { getDetectionEngineUrl, useFormatUrl } from '../../../../common/components/link_to'; import { VIEW_ALERTS } from '../../../pages/translations'; -import { LastUpdatedAt, SEVERITY_COLOR } from '../utils'; +import { SEVERITY_COLOR } from '../utils'; import { FormattedCount } from '../../../../common/components/formatted_number'; import { ChartLabel } from './chart_label'; import { Legend } from '../../../../common/components/charts/legend'; import { emptyDonutColor } from '../../../../common/components/charts/donutchart_empty'; -import { LinkButton } from '../../../../common/components/links'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; +import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; +import { useNavigateToTimeline } from '../hooks/use_navigate_to_timeline'; -const donutHeight = 120; const StyledFlexItem = styled(EuiFlexItem)` padding: 0 4px; `; @@ -52,6 +62,7 @@ const StyledLegendFlexItem = styled(EuiFlexItem)` interface AlertsByStatusProps { signalIndexName: string | null; + entityFilter?: EntityFilter; } const legendField = 'kibana.alert.severity'; @@ -63,28 +74,31 @@ const chartConfigs: Array<{ key: Severity; label: string; color: string }> = [ ]; const DETECTION_RESPONSE_ALERTS_BY_STATUS_ID = 'detection-response-alerts-by-status'; -export const AlertsByStatus = ({ signalIndexName }: AlertsByStatusProps) => { +const eventKindSignalFilter: EntityFilter = { + field: 'event.kind', + value: 'signal', +}; + +export const AlertsByStatus = ({ signalIndexName, entityFilter }: AlertsByStatusProps) => { const { toggleStatus, setToggleStatus } = useQueryToggle(DETECTION_RESPONSE_ALERTS_BY_STATUS_ID); - const { formatUrl, search: urlSearch } = useFormatUrl(SecurityPageName.alerts); - const { navigateTo } = useNavigation(); - const goToAlerts = useCallback( - (ev) => { - ev.preventDefault(); - navigateTo({ - deepLinkId: SecurityPageName.alerts, - path: getDetectionEngineUrl(urlSearch), - }); - }, - [navigateTo, urlSearch] - ); + const { openEntityInTimeline } = useNavigateToTimeline(); + const { onClick: goToAlerts, href } = useGetSecuritySolutionLinkProps()({ + deepLinkId: SecurityPageName.alerts, + }); + + const isLargerBreakpoint = useIsWithinMinBreakpoint('xl'); + const isSmallBreakpoint = useIsWithinMaxBreakpoint('s'); + const donutHeight = isSmallBreakpoint || isLargerBreakpoint ? 120 : 90; const detailsButtonOptions = useMemo( () => ({ name: VIEW_ALERTS, - href: formatUrl(getDetectionEngineUrl()), - onClick: goToAlerts, + href: entityFilter ? undefined : href, + onClick: entityFilter + ? () => openEntityInTimeline([entityFilter, eventKindSignalFilter]) + : goToAlerts, }), - [formatUrl, goToAlerts] + [entityFilter, href, goToAlerts, openEntityInTimeline] ); const { @@ -92,9 +106,10 @@ export const AlertsByStatus = ({ signalIndexName }: AlertsByStatusProps) => { isLoading: loading, updatedAt, } = useAlertsByStatus({ + entityFilter, signalIndexName, - queryId: DETECTION_RESPONSE_ALERTS_BY_STATUS_ID, skip: !toggleStatus, + queryId: DETECTION_RESPONSE_ALERTS_BY_STATUS_ID, }); const legendItems: LegendItem[] = useMemo( () => @@ -131,7 +146,7 @@ export const AlertsByStatus = ({ signalIndexName }: AlertsByStatusProps) => { )} } inspectMultiple diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts index ab9dd704dcc23..bf926f33e3a5e 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts @@ -26,11 +26,35 @@ export const severityLabels: Record = { low: STATUS_LOW_LABEL, }; -export const getAlertsByStatusQuery = ({ from, to }: { from: string; to: string }) => ({ +export interface EntityFilter { + field: string; + value: string; +} + +export const getAlertsByStatusQuery = ({ + from, + to, + entityFilter, +}: { + from: string; + to: string; + entityFilter?: EntityFilter; +}) => ({ size: 0, query: { bool: { - filter: [{ range: { '@timestamp': { gte: from, lte: to } } }], + filter: [ + { range: { '@timestamp': { gte: from, lte: to } } }, + ...(entityFilter + ? [ + { + term: { + [entityFilter.field]: entityFilter.value, + }, + }, + ] + : []), + ], }, }, aggs: { @@ -79,6 +103,7 @@ export interface UseAlertsByStatusProps { queryId: string; signalIndexName: string | null; skip?: boolean; + entityFilter?: EntityFilter; } export type UseAlertsByStatus = (props: UseAlertsByStatusProps) => { @@ -88,6 +113,7 @@ export type UseAlertsByStatus = (props: UseAlertsByStatusProps) => { }; export const useAlertsByStatus: UseAlertsByStatus = ({ + entityFilter, queryId, signalIndexName, skip = false, @@ -107,6 +133,7 @@ export const useAlertsByStatus: UseAlertsByStatus = ({ query: getAlertsByStatusQuery({ from, to, + entityFilter, }), indexName: signalIndexName, skip, @@ -118,9 +145,10 @@ export const useAlertsByStatus: UseAlertsByStatus = ({ getAlertsByStatusQuery({ from, to, + entityFilter, }) ); - }, [setAlertsQuery, from, to]); + }, [setAlertsQuery, from, to, entityFilter]); useEffect(() => { if (data == null) { diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx index e71935d217c55..459131164dbe2 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx @@ -13,7 +13,7 @@ import styled from 'styled-components'; import { FormattedNumber } from '@kbn/i18n-react'; import numeral from '@elastic/numeral'; import { BarChart } from '../../../../common/components/charts/barchart'; -import { LastUpdatedAt } from '../utils'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { HeaderSection } from '../../../../common/components/header_section'; import { diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/cases_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/cases_table.tsx index e5fdeb6c31638..c6d819699a8db 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/cases_table.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/cases_table.tsx @@ -25,12 +25,12 @@ import { FormattedCount } from '../../../../common/components/formatted_number'; import { HeaderSection } from '../../../../common/components/header_section'; import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { CaseDetailsLink } from '../../../../common/components/links'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import type { NavigateTo, GetAppUrl } from '../../../../common/lib/kibana'; import { useNavigation } from '../../../../common/lib/kibana'; import * as i18n from '../translations'; -import { LastUpdatedAt } from '../utils'; import { StatusBadge } from './status_badge'; import type { CaseItem } from './use_case_items'; import { useCaseItems } from './use_case_items'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx index 5062c4ab83840..f74936d85a937 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/hooks/use_navigate_to_timeline.tsx @@ -5,19 +5,35 @@ * 2.0. */ +import { useMemo } from 'react'; import { useDispatch } from 'react-redux'; -import { getDataProvider } from '../../../../common/components/event_details/table/use_action_cell_data_provider'; -import { sourcererActions } from '../../../../common/store/sourcerer'; +import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; +import { sourcererActions } from '../../../../common/store/sourcerer'; +import { getDataProvider } from '../../../../common/components/event_details/table/use_action_cell_data_provider'; import type { DataProvider } from '../../../../../common/types/timeline'; import { TimelineId, TimelineType } from '../../../../../common/types/timeline'; import { useCreateTimeline } from '../../../../timelines/components/timeline/properties/use_create_timeline'; import { updateProviders } from '../../../../timelines/store/timeline/actions'; +import { sourcererSelectors } from '../../../../common/store'; + +export interface Filter { + field: string; + value: string; +} export const useNavigateToTimeline = () => { const dispatch = useDispatch(); + const getDataViewsSelector = useMemo( + () => sourcererSelectors.getSourcererDataViewsSelector(), + [] + ); + const { defaultDataView, signalIndexName } = useDeepEqualSelector((state) => + getDataViewsSelector(state) + ); + const clearTimeline = useCreateTimeline({ timelineId: TimelineId.active, timelineType: TimelineType.default, @@ -33,17 +49,32 @@ export const useNavigateToTimeline = () => { providers: [dataProvider], }) ); - // Only show detection alerts - // (This is required so the timeline event count matches the prevalence count) + dispatch( sourcererActions.setSelectedDataView({ id: SourcererScopeName.timeline, - selectedDataViewId: 'security-solution-default', - selectedPatterns: ['.alerts-security.alerts-default'], + selectedDataViewId: defaultDataView.id, + selectedPatterns: [signalIndexName || ''], }) ); }; + const openEntityInTimeline = (entityFilters: [Filter, ...Filter[]]) => { + const mainFilter = entityFilters.shift(); + + if (mainFilter) { + const dataProvider = getDataProvider(mainFilter.field, '', mainFilter.value); + + for (const filter of entityFilters) { + dataProvider.and.push(getDataProvider(filter.field, '', filter.value)); + } + + navigateToTimeline(dataProvider); + } + }; + + // TODO: Replace the usage of functions with openEntityInTimeline + const openHostInTimeline = ({ hostName, severity }: { hostName: string; severity?: string }) => { const dataProvider = getDataProvider('host.name', '', hostName); @@ -70,6 +101,7 @@ export const useNavigateToTimeline = () => { }; return { + openEntityInTimeline, openHostInTimeline, openRuleInTimeline, openUserInTimeline, diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx index 3ae0d5e1384c3..b5ec1de73fa39 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx @@ -23,11 +23,12 @@ import { FormattedCount } from '../../../../common/components/formatted_number'; import { HeaderSection } from '../../../../common/components/header_section'; import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { HostDetailsLink } from '../../../../common/components/links'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { useNavigateToTimeline } from '../hooks/use_navigate_to_timeline'; import * as i18n from '../translations'; -import { ITEMS_PER_PAGE, LastUpdatedAt, SEVERITY_COLOR } from '../utils'; +import { ITEMS_PER_PAGE, SEVERITY_COLOR } from '../utils'; import type { HostAlertsItem } from './use_host_alerts_items'; import { useHostAlertsItems } from './use_host_alerts_items'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx index 3e9e79a39de58..59a92896ddb85 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx @@ -22,7 +22,7 @@ import { FormattedRelative } from '@kbn/i18n-react'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import { HeaderSection } from '../../../../common/components/header_section'; -import { LastUpdatedAt, SEVERITY_COLOR } from '../utils'; +import { SEVERITY_COLOR } from '../utils'; import * as i18n from '../translations'; import type { RuleAlertsItem } from './use_rule_alerts_items'; import { useRuleAlertsItems } from './use_rule_alerts_items'; @@ -31,7 +31,8 @@ import { useNavigation } from '../../../../common/lib/kibana'; import { SecurityPageName } from '../../../../../common/constants'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; -import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { BUTTON_CLASS as INSPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { FormattedCount } from '../../../../common/components/formatted_number'; import { useNavigateToTimeline } from '../hooks/use_navigate_to_timeline'; @@ -125,7 +126,7 @@ export const RuleAlertsTable = React.memo(({ signalIndexNa ); return ( - + export const ALERTS_TEXT = i18n.translate('xpack.securitySolution.detectionResponse.alerts', { defaultMessage: 'Alerts', }); +export const ALERTS_BY_STATUS_TEXT = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus', + { + defaultMessage: 'Alerts by Status', + } +); + export const UPDATING = i18n.translate('xpack.securitySolution.detectionResponse.updating', { defaultMessage: 'Updating...', }); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx index a279b6ced4a1c..c50f5976360ed 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx @@ -23,11 +23,12 @@ import { FormattedCount } from '../../../../common/components/formatted_number'; import { HeaderSection } from '../../../../common/components/header_section'; import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { UserDetailsLink } from '../../../../common/components/links'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { useNavigateToTimeline } from '../hooks/use_navigate_to_timeline'; import * as i18n from '../translations'; -import { ITEMS_PER_PAGE, LastUpdatedAt, SEVERITY_COLOR } from '../utils'; +import { ITEMS_PER_PAGE, SEVERITY_COLOR } from '../utils'; import type { UserAlertsItem } from './use_user_alerts_items'; import { useUserAlertsItems } from './use_user_alerts_items'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx index 0a602b21f676f..76b690e0fbf0a 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx @@ -5,13 +5,6 @@ * 2.0. */ -import React from 'react'; - -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { FormattedRelative } from '@kbn/i18n-react'; - -import * as i18n from './translations'; - export const SEVERITY_COLOR = { critical: '#E7664C', high: '#DA8B45', @@ -22,28 +15,6 @@ export const SEVERITY_COLOR = { export const ITEMS_PER_PAGE = 4; const MAX_ALLOWED_RESULTS = 100; -export interface LastUpdatedAtProps { - updatedAt: number; - isUpdating: boolean; -} - -export const LastUpdatedAt: React.FC = ({ isUpdating, updatedAt }) => ( - - {isUpdating ? ( - {i18n.UPDATING} - ) : ( - - <>{i18n.UPDATED} - - - )} - -); - /** * While there could be more than 100 hosts or users we only want to show 25 pages of results, * and the host count cardinality result will always be the total count diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx index dea9314a3645f..2d8491879d060 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx @@ -10,7 +10,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiInMemoryTable, EuiPanel } from '@elastic/ import { ML_PAGES, useMlHref } from '@kbn/ml-plugin/public'; import { HeaderSection } from '../../../../common/components/header_section'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { LastUpdatedAt } from '../../detection_response/utils'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import * as i18n from './translations'; import { useNotableAnomaliesSearch } from '../../../../common/components/ml/anomaly/use_anomalies_search'; import { useAnomaliesColumns } from './columns'; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx index 9a0552f854a08..123f190446255 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx @@ -14,7 +14,7 @@ import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/ import { getTabsOnHostsUrl } from '../../../../common/components/link_to/redirect_to_hosts'; import { HostsTableType, HostsType } from '../../../../hosts/store/model'; import { getHostRiskScoreColumns } from './columns'; -import { LastUpdatedAt } from '../../detection_response/utils'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { HeaderSection } from '../../../../common/components/header_section'; import { useHostRiskScore, useHostRiskScoreKpi } from '../../../../risk_score/containers'; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/user_risk_score/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/user_risk_score/index.tsx index a8b85bd2ac281..fe4a72f466ea0 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/user_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/user_risk_score/index.tsx @@ -10,7 +10,7 @@ import { useDispatch } from 'react-redux'; import { RiskScoresDeprecated } from '../../../../common/components/risk_score/risk_score_deprecated'; import { SeverityFilterGroup } from '../../../../common/components/severity/severity_filter_group'; import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; -import { LastUpdatedAt } from '../../detection_response/utils'; +import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { HeaderSection } from '../../../../common/components/header_section'; import type { RiskSeverity } from '../../../../../common/search_strategy'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; diff --git a/x-pack/plugins/security_solution/public/users/pages/details/index.tsx b/x-pack/plugins/security_solution/public/users/pages/details/index.tsx index a3cb81a7d4a5b..4e2c093803096 100644 --- a/x-pack/plugins/security_solution/public/users/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/users/pages/details/index.tsx @@ -5,13 +5,23 @@ * 2.0. */ -import { EuiSpacer, EuiWindowEvent } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiSpacer, + EuiWindowEvent, +} from '@elastic/eui'; import { noop } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo } from 'react'; import { useDispatch } from 'react-redux'; -import type { Filter } from '@kbn/es-query'; import { getEsQueryConfig } from '@kbn/data-plugin/common'; +import type { Filter } from '@kbn/es-query'; + +import { AlertsByStatus } from '../../../overview/components/detection_response/alerts_by_status'; +import { useSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_signal_index'; +import { AlertCountByRuleByStatus } from '../../../common/components/alert_count_by_status'; import { InputsModelId } from '../../../common/store/inputs/constants'; import { SecurityPageName } from '../../../app/types'; import { FiltersGlobal } from '../../../common/components/filters_global'; @@ -23,6 +33,7 @@ import { useGlobalTime } from '../../../common/containers/use_global_time'; import { useKibana } from '../../../common/lib/kibana'; import { convertToBuildEsQuery } from '../../../common/lib/keury'; import { inputsSelectors } from '../../../common/store'; +import { useAlertsPrivileges } from '../../../detections/containers/detection_engine/alerts/use_alerts_privileges'; import { setUsersDetailsTablesActivePageToZero } from '../../store/actions'; import { setAbsoluteRangeDatePicker } from '../../../common/store/inputs/actions'; import { SpyRoute } from '../../../common/utils/route/spy_routes'; @@ -53,7 +64,9 @@ import { UsersType } from '../../store/model'; import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { LandingPageComponent } from '../../../common/components/landing_page'; + const QUERY_ID = 'UsersDetailsQueryId'; +const ES_USER_FIELD = 'user.name'; const UsersDetailsComponent: React.FC = ({ detailName, @@ -73,6 +86,10 @@ const UsersDetailsComponent: React.FC = ({ const query = useDeepEqualSelector(getGlobalQuerySelector); const filters = useDeepEqualSelector(getGlobalFiltersQuerySelector); + const { signalIndexName } = useSignalIndex(); + const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const canReadAlerts = hasKibanaREAD && hasIndexRead; + const { to, from, deleteQuery, setQuery, isInitializing } = useGlobalTime(); const { globalFullScreen } = useGlobalFullScreen(); @@ -132,6 +149,14 @@ const UsersDetailsComponent: React.FC = ({ [dispatch] ); + const entityFilter = useMemo( + () => ({ + field: ES_USER_FIELD, + value: detailName, + }), + [detailName] + ); + return ( <> {indicesExist ? ( @@ -143,7 +168,6 @@ const UsersDetailsComponent: React.FC = ({ = ({ } title={detailName} /> + = ({ /> )} - + + {canReadAlerts && ( + <> + + + + + + + + + + + )} + = ({ isPlatinumOrTrialLicense )} /> - - Date: Wed, 21 Sep 2022 01:15:57 +0200 Subject: [PATCH 23/55] [Osquery] Add support for differential logs (#140660) --- x-pack/plugins/osquery/common/constants.ts | 2 + .../osquery/common/schemas/common/index.ts | 1 + .../osquery/common/schemas/common/schemas.ts | 10 + .../osquery/common/schemas/common/utils.ts | 60 +- .../create_saved_query_request_schema.ts | 4 + .../cypress/e2e/all/add_integration.cy.ts | 4 +- .../osquery/cypress/e2e/all/packs.cy.ts | 2 +- .../cypress/e2e/all/saved_queries.cy.ts | 11 +- .../public/actions/use_live_query_details.ts | 4 +- .../osquery/public/agents/agents_table.tsx | 2 +- .../plugins/osquery/public/common/helpers.ts | 9 - x-pack/plugins/osquery/public/form/index.ts | 2 +- .../osquery/public/form/interval_field.tsx | 4 +- .../osquery/public/form/query_id_field.tsx | 3 +- .../public/form/results_type_field.tsx | 155 ++++ x-pack/plugins/osquery/public/form/types.ts | 7 - .../osquery/public/form/version_field.tsx | 3 +- .../public/live_queries/form/index.tsx | 55 +- .../form/live_query_query_field.tsx | 29 +- .../form/pack_queries_status_table.tsx | 3 +- .../osquery/public/live_queries/index.tsx | 4 +- .../public/packs/form/description_field.tsx | 49 + .../osquery/public/packs/form/index.tsx | 177 ++-- .../osquery/public/packs/form/name_field.tsx | 60 ++ .../packs/form/policy_id_combobox_field.tsx | 112 ++- .../public/packs/form/queries_field.tsx | 170 ++-- .../osquery/public/packs/form/utils.ts | 23 +- .../public/packs/pack_queries_table.tsx | 7 +- .../queries/ecs_mapping_editor_field.tsx | 856 ++++++++++-------- .../public/packs/queries/query_flyout.tsx | 37 +- .../packs/queries/use_pack_query_form.tsx | 50 +- x-pack/plugins/osquery/public/packs/types.ts | 2 +- .../osquery/public/packs/use_create_pack.ts | 4 +- .../routes/saved_queries/list/index.tsx | 3 +- .../public/saved_queries/form/index.tsx | 15 +- .../form/use_saved_query_form.tsx | 31 +- .../saved_queries/saved_query_flyout.tsx | 2 - .../saved_queries/use_create_saved_query.ts | 7 +- .../osquery_response_action_type/index.tsx | 35 +- .../pack_field_wrapper.tsx | 9 +- x-pack/plugins/osquery/server/common/types.ts | 4 + .../lib/saved_query/saved_object_mappings.ts | 3 + .../osquery/server/lib/telemetry/filters.ts | 2 + .../osquery/server/lib/telemetry/helpers.ts | 2 + .../osquery/server/lib/telemetry/sender.ts | 12 + .../server/routes/pack/create_pack_route.ts | 2 + .../server/routes/pack/update_pack_route.ts | 2 + .../osquery/server/routes/pack/utils.test.ts | 5 +- .../osquery/server/routes/pack/utils.ts | 12 +- .../saved_query/create_saved_query_route.ts | 18 +- .../saved_query/update_saved_query_route.ts | 6 + 51 files changed, 1178 insertions(+), 913 deletions(-) create mode 100644 x-pack/plugins/osquery/public/form/results_type_field.tsx create mode 100644 x-pack/plugins/osquery/public/packs/form/description_field.tsx create mode 100644 x-pack/plugins/osquery/public/packs/form/name_field.tsx diff --git a/x-pack/plugins/osquery/common/constants.ts b/x-pack/plugins/osquery/common/constants.ts index 4d6be1f3f2ae8..1307d719a5835 100644 --- a/x-pack/plugins/osquery/common/constants.ts +++ b/x-pack/plugins/osquery/common/constants.ts @@ -11,3 +11,5 @@ export const OSQUERY_INTEGRATION_NAME = 'osquery_manager'; export const BASE_PATH = '/app/osquery'; export const ACTIONS_INDEX = `.logs-${OSQUERY_INTEGRATION_NAME}.actions`; export const ACTION_RESPONSES_INDEX = `.logs-${OSQUERY_INTEGRATION_NAME}.action.responses`; + +export const DEFAULT_PLATFORM = 'linux,windows,darwin'; diff --git a/x-pack/plugins/osquery/common/schemas/common/index.ts b/x-pack/plugins/osquery/common/schemas/common/index.ts index 7aa477e1db748..69a2c103f43e7 100644 --- a/x-pack/plugins/osquery/common/schemas/common/index.ts +++ b/x-pack/plugins/osquery/common/schemas/common/index.ts @@ -6,3 +6,4 @@ */ export * from './schemas'; +export * from './utils'; diff --git a/x-pack/plugins/osquery/common/schemas/common/schemas.ts b/x-pack/plugins/osquery/common/schemas/common/schemas.ts index 0e7ae280fca84..5aa1d35437530 100644 --- a/x-pack/plugins/osquery/common/schemas/common/schemas.ts +++ b/x-pack/plugins/osquery/common/schemas/common/schemas.ts @@ -48,6 +48,16 @@ export type Interval = t.TypeOf; export const intervalOrUndefined = t.union([interval, t.undefined]); export type IntervalOrUndefined = t.TypeOf; +export const snapshot = t.boolean; +export type Snapshot = t.TypeOf; +export const snapshotOrUndefined = t.union([snapshot, t.undefined]); +export type SnapshotOrUndefined = t.TypeOf; + +export const removed = t.boolean; +export type Removed = t.TypeOf; +export const removedOrUndefined = t.union([removed, t.undefined]); +export type RemovedOrUndefined = t.TypeOf; + export const savedQueryId = t.string; export type SavedQueryId = t.TypeOf; export const savedQueryIdOrUndefined = t.union([savedQueryId, t.undefined]); diff --git a/x-pack/plugins/osquery/common/schemas/common/utils.ts b/x-pack/plugins/osquery/common/schemas/common/utils.ts index 5e515a756c61f..42326a5798ddd 100644 --- a/x-pack/plugins/osquery/common/schemas/common/utils.ts +++ b/x-pack/plugins/osquery/common/schemas/common/utils.ts @@ -5,18 +5,21 @@ * 2.0. */ -import { isEmpty, map, reduce } from 'lodash'; +import { isEmpty, reduce } from 'lodash'; +import type { DefaultValues } from 'react-hook-form'; import type { ECSMapping } from './schemas'; -export const convertECSMappingToObject = ( - ecsMapping: Array<{ - key: string; - result: { - type: string; - value: string; - }; - }> -): ECSMapping => +export type { ECSMapping }; + +export type ECSMappingArray = Array<{ + key: string; + result: { + type: string; + value: string | string[]; + }; +}>; + +export const convertECSMappingToObject = (ecsMapping: ECSMappingArray): ECSMapping => reduce( ecsMapping, (acc, value) => { @@ -28,23 +31,26 @@ export const convertECSMappingToObject = ( return acc; }, - {} as Record + {} as ECSMapping ); -export type EcsMappingFormValueArray = Array<{ - key: string; - result: { - type: string; - value: string; - }; -}>; -export const convertECSMappingToFormValue = ( - mapping?: Record> -): EcsMappingFormValueArray => - map(mapping, (value, key) => ({ - key, - result: { - type: Object.keys(value)[0], - value: Object.values(value)[0], +export const convertECSMappingToArray = ( + ecsMapping: DefaultValues | undefined +): ECSMappingArray => + reduce( + ecsMapping, + (acc, value, key) => { + if (value) { + acc.push({ + key, + result: { + type: Object.keys(value)[0], + value: Object.values(value as string | string[])[0], + }, + }); + } + + return acc; }, - })); + [] as ECSMappingArray + ); diff --git a/x-pack/plugins/osquery/common/schemas/routes/saved_query/create_saved_query_request_schema.ts b/x-pack/plugins/osquery/common/schemas/routes/saved_query/create_saved_query_request_schema.ts index b58ed0e789cd7..57766307216f0 100644 --- a/x-pack/plugins/osquery/common/schemas/routes/saved_query/create_saved_query_request_schema.ts +++ b/x-pack/plugins/osquery/common/schemas/routes/saved_query/create_saved_query_request_schema.ts @@ -15,6 +15,8 @@ import { query, versionOrUndefined, interval, + snapshotOrUndefined, + removedOrUndefined, ecsMappingOrUndefined, } from '../../common/schemas'; import type { RequiredKeepUndefined } from '../../../types'; @@ -26,6 +28,8 @@ export const createSavedQueryRequestSchema = t.type({ query, version: versionOrUndefined, interval, + snapshot: snapshotOrUndefined, + removed: removedOrUndefined, ecs_mapping: ecsMappingOrUndefined, }); diff --git a/x-pack/plugins/osquery/cypress/e2e/all/add_integration.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/add_integration.cy.ts index 38e6d6f30a661..5204fc8d16c93 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/add_integration.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/add_integration.cy.ts @@ -28,7 +28,7 @@ describe('ALL - Add Integration', () => { runKbnArchiverScript(ArchiverMethod.UNLOAD, 'saved_query'); }); - it('should add the old integration and be able to upgrade it', () => { + it.skip('should add the old integration and be able to upgrade it', () => { const oldVersion = '0.7.4'; cy.visit(OLD_OSQUERY_MANAGER); @@ -78,7 +78,7 @@ describe('ALL - Add Integration', () => { cy.contains('osquery_manager-'); }); - it('should have integration and packs copied when upgrading integration', () => { + it.skip('should have integration and packs copied when upgrading integration', () => { const packageName = 'osquery_manager'; const oldVersion = '1.2.0'; diff --git a/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts index b53651afa7157..0d77b7f4ff5f1 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/packs.cy.ts @@ -288,7 +288,7 @@ describe('ALL - Packs', () => { .click(); cy.contains(/^Delete integration$/).click(); closeModalIfVisible(); - cy.contains(/^Deleted integration 'osquery_manager-3'$/); + cy.contains(/^Deleted integration 'osquery_manager-*/); navigateTo('app/osquery/packs'); cy.contains(REMOVING_PACK).click(); cy.contains(`${REMOVING_PACK} details`).should('exist'); diff --git a/x-pack/plugins/osquery/cypress/e2e/all/saved_queries.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/saved_queries.cy.ts index e4d76ce9438eb..64fce2e3e0376 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/saved_queries.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/saved_queries.cy.ts @@ -9,17 +9,18 @@ import { navigateTo } from '../../tasks/navigation'; import { login } from '../../tasks/login'; import { ROLES } from '../../test'; +import { getSavedQueriesComplexTest } from '../../tasks/saved_queries'; +import { getRandomInt } from '../../tasks/helpers'; describe('ALL - Saved queries', () => { - // const randomNumber = getRandomInt(); - // const SAVED_QUERY_ID = `Saved-Query-Id-${randomNumber}`; - // const SAVED_QUERY_DESCRIPTION = `Test saved query description ${randomNumber}`; + const randomNumber = getRandomInt(); + const SAVED_QUERY_ID = `Saved-Query-Id-${randomNumber}`; + const SAVED_QUERY_DESCRIPTION = `Test saved query description ${randomNumber}`; beforeEach(() => { login(ROLES.soc_manager); navigateTo('/app/osquery'); }); - // TODO usnkip after FF - // getSavedQueriesComplexTest(SAVED_QUERY_ID, SAVED_QUERY_DESCRIPTION); + getSavedQueriesComplexTest(SAVED_QUERY_ID, SAVED_QUERY_DESCRIPTION); }); diff --git a/x-pack/plugins/osquery/public/actions/use_live_query_details.ts b/x-pack/plugins/osquery/public/actions/use_live_query_details.ts index e5d8600be9c86..9c498c3ba82e5 100644 --- a/x-pack/plugins/osquery/public/actions/use_live_query_details.ts +++ b/x-pack/plugins/osquery/public/actions/use_live_query_details.ts @@ -9,7 +9,7 @@ import { useQuery } from '@tanstack/react-query'; import { i18n } from '@kbn/i18n'; import { filter } from 'lodash'; -import type { EcsMappingFormField } from '../packs/queries/ecs_mapping_editor_field'; +import type { ECSMapping } from '../../common/schemas/common'; import { useKibana } from '../common/lib/kibana'; import type { ESTermQuery } from '../../common/typed_json'; import { useErrorToast } from '../common/hooks/use_error_toast'; @@ -27,7 +27,7 @@ export interface PackQueriesQuery { id: string; query: string; agents: string[]; - ecs_mapping?: EcsMappingFormField[]; + ecs_mapping?: ECSMapping; version?: string; platform?: string; saved_query_id?: string; diff --git a/x-pack/plugins/osquery/public/agents/agents_table.tsx b/x-pack/plugins/osquery/public/agents/agents_table.tsx index 2d05780d6545f..9f1d6e59b8168 100644 --- a/x-pack/plugins/osquery/public/agents/agents_table.tsx +++ b/x-pack/plugins/osquery/public/agents/agents_table.tsx @@ -208,4 +208,4 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh AgentsTableComponent.displayName = 'AgentsTable'; -export const AgentsTable = React.memo(AgentsTableComponent); +export const AgentsTable = React.memo(AgentsTableComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/common/helpers.ts b/x-pack/plugins/osquery/public/common/helpers.ts index 6ac79d9ed8870..7697e1d59d5ce 100644 --- a/x-pack/plugins/osquery/public/common/helpers.ts +++ b/x-pack/plugins/osquery/public/common/helpers.ts @@ -42,12 +42,3 @@ export const getInspectResponse = ( response: response != null ? [JSON.stringify(response.rawResponse, null, 2)] : prevResponse?.response, }); - -export const prepareEcsFieldsToValidate = (ecsMapping: Array<{ id: string }>): string[] => - ecsMapping - ?.map((_: unknown, index: number) => [ - `ecs_mapping[${index}].result.value`, - `ecs_mapping[${index}].key`, - ]) - .join(',') - .split(','); diff --git a/x-pack/plugins/osquery/public/form/index.ts b/x-pack/plugins/osquery/public/form/index.ts index 31ea2ac171c88..623477aaa0d16 100644 --- a/x-pack/plugins/osquery/public/form/index.ts +++ b/x-pack/plugins/osquery/public/form/index.ts @@ -9,4 +9,4 @@ export { VersionField } from './version_field'; export { QueryDescriptionField } from './query_description_field'; export { IntervalField } from './interval_field'; export { QueryIdField } from './query_id_field'; -export type { FormField } from './types'; +export { ResultsTypeField } from './results_type_field'; diff --git a/x-pack/plugins/osquery/public/form/interval_field.tsx b/x-pack/plugins/osquery/public/form/interval_field.tsx index d8d1a01804d65..9b5c2001ce2a6 100644 --- a/x-pack/plugins/osquery/public/form/interval_field.tsx +++ b/x-pack/plugins/osquery/public/form/interval_field.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React, { useCallback, useMemo } from 'react'; - +import deepEqual from 'fast-deep-equal'; import { useController } from 'react-hook-form'; import type { EuiFieldNumberProps } from '@elastic/eui'; import { EuiFieldNumber, EuiFormRow } from '@elastic/eui'; @@ -79,4 +79,4 @@ const IntervalFieldComponent = ({ euiFieldProps }: IntervalFieldProps) => { ); }; -export const IntervalField = React.memo(IntervalFieldComponent); +export const IntervalField = React.memo(IntervalFieldComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/form/query_id_field.tsx b/x-pack/plugins/osquery/public/form/query_id_field.tsx index 5910cb9f08dc7..d9f8d362ea3ec 100644 --- a/x-pack/plugins/osquery/public/form/query_id_field.tsx +++ b/x-pack/plugins/osquery/public/form/query_id_field.tsx @@ -8,6 +8,7 @@ import React, { useMemo } from 'react'; import { useController } from 'react-hook-form'; import { EuiFieldText, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import deepEqual from 'fast-deep-equal'; import { createFormIdFieldValidations } from '../packs/queries/validations'; interface QueryIdFieldProps { @@ -49,4 +50,4 @@ const QueryIdFieldComponent = ({ idSet, euiFieldProps }: QueryIdFieldProps) => { ); }; -export const QueryIdField = React.memo(QueryIdFieldComponent); +export const QueryIdField = React.memo(QueryIdFieldComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/form/results_type_field.tsx b/x-pack/plugins/osquery/public/form/results_type_field.tsx new file mode 100644 index 0000000000000..55bbe69397f97 --- /dev/null +++ b/x-pack/plugins/osquery/public/form/results_type_field.tsx @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useEffect, useState } from 'react'; +import { + EuiBetaBadge, + EuiFormRow, + EuiSuperSelect, + EuiFlexGroup, + EuiFlexItem, + EuiText, +} from '@elastic/eui'; +import { useController } from 'react-hook-form'; +import { FormattedMessage } from '@kbn/i18n-react'; +import deepEqual from 'fast-deep-equal'; +import { i18n } from '@kbn/i18n'; + +const SNAPSHOT_OPTION = { + value: 'snapshot', + inputDisplay: ( + + ), +}; + +const DIFFERENTIAL_OPTION = { + value: 'differential', + inputDisplay: ( + + ), +}; + +const DIFFERENTIAL_ADDED_ONLY_OPTION = { + value: 'added_only', + inputDisplay: ( + + ), +}; + +const FIELD_OPTIONS = [SNAPSHOT_OPTION, DIFFERENTIAL_OPTION, DIFFERENTIAL_ADDED_ONLY_OPTION]; + +interface ResultsTypeFieldProps { + euiFieldProps?: Record; +} + +const ResultsTypeFieldComponent: React.FC = ({ euiFieldProps = {} }) => { + const [selectedOption, setSelectedOption] = useState(SNAPSHOT_OPTION.value); + const { + field: { onChange: onSnapshotChange, value: snapshotValue }, + } = useController({ + name: 'snapshot', + defaultValue: true, + }); + + const { + field: { onChange: onRemovedChange, value: removedValue }, + } = useController({ + name: 'removed', + defaultValue: false, + }); + + const handleChange = useCallback( + (newValue) => { + if (newValue === SNAPSHOT_OPTION.value) { + onSnapshotChange(true); + onRemovedChange(false); + } + + if (newValue === DIFFERENTIAL_OPTION.value) { + onSnapshotChange(false); + onRemovedChange(true); + } + + if (newValue === DIFFERENTIAL_ADDED_ONLY_OPTION.value) { + onSnapshotChange(false); + onRemovedChange(false); + } + }, + [onRemovedChange, onSnapshotChange] + ); + + useEffect(() => { + setSelectedOption(() => { + if (snapshotValue) { + return SNAPSHOT_OPTION.value; + } + + if (!snapshotValue && removedValue) { + return DIFFERENTIAL_OPTION.value; + } + + if (!snapshotValue && !removedValue) { + return DIFFERENTIAL_ADDED_ONLY_OPTION.value; + } + + return SNAPSHOT_OPTION.value; + }); + }, [removedValue, snapshotValue]); + + return ( + + + + + + + + + } + labelAppend={ + + + + + + } + fullWidth + > + + + ); +}; + +export const ResultsTypeField = React.memo(ResultsTypeFieldComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/form/types.ts b/x-pack/plugins/osquery/public/form/types.ts index 14f013ac2b012..14b7263c1aa1d 100644 --- a/x-pack/plugins/osquery/public/form/types.ts +++ b/x-pack/plugins/osquery/public/form/types.ts @@ -8,13 +8,6 @@ import type React from 'react'; import type { ReactNode } from 'react'; -export interface FormField { - name: string; - onChange: (data: T) => void; - value: T; - onBlur?: () => void; -} - export interface FormFieldProps { name: string; label: string | Element; diff --git a/x-pack/plugins/osquery/public/form/version_field.tsx b/x-pack/plugins/osquery/public/form/version_field.tsx index f97e26b79a651..ec4a927676e85 100644 --- a/x-pack/plugins/osquery/public/form/version_field.tsx +++ b/x-pack/plugins/osquery/public/form/version_field.tsx @@ -11,6 +11,7 @@ import type { EuiComboBoxOptionOption } from '@elastic/eui'; import { EuiFormRow, EuiComboBox, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { useController } from 'react-hook-form'; import { FormattedMessage } from '@kbn/i18n-react'; +import deepEqual from 'fast-deep-equal'; interface VersionFieldProps { euiFieldProps?: Record; @@ -85,4 +86,4 @@ const VersionFieldComponent = ({ euiFieldProps = {} }: VersionFieldProps) => { ); }; -export const VersionField = React.memo(VersionFieldComponent); +export const VersionField = React.memo(VersionFieldComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/live_queries/form/index.tsx b/x-pack/plugins/osquery/public/live_queries/form/index.tsx index 5c4c891f99301..a4dc1e97a7c01 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/index.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/index.tsx @@ -9,17 +9,12 @@ import { EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/e import { FormattedMessage } from '@kbn/i18n-react'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useForm as useHookForm, FormProvider } from 'react-hook-form'; -import { isEmpty, map, find, pickBy } from 'lodash'; +import { isEmpty, find, pickBy } from 'lodash'; import type { AddToTimelinePayload } from '../../timelines/get_add_to_timeline'; import { QueryPackSelectable } from './query_pack_selectable'; import type { SavedQuerySOFormData } from '../../saved_queries/form/use_saved_query_form'; -import type { - EcsMappingFormField, - EcsMappingSerialized, -} from '../../packs/queries/ecs_mapping_editor_field'; -import { defaultEcsFormData } from '../../packs/queries/ecs_mapping_editor_field'; -import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; +import type { ECSMapping } from '../../../common/schemas/common/utils'; import { useKibana } from '../../common/lib/kibana'; import { ResultTabs } from '../../routes/saved_queries/edit/tabs'; import { SavedQueryFlyout } from '../../saved_queries'; @@ -37,7 +32,7 @@ export interface LiveQueryFormFields { query?: string; agentSelection: AgentSelection; savedQueryId?: string | null; - ecs_mapping: EcsMappingFormField[]; + ecs_mapping: ECSMapping; packId: string[]; } @@ -45,7 +40,7 @@ interface DefaultLiveQueryFormFields { query?: string; agentSelection?: AgentSelection; savedQueryId?: string | null; - ecs_mapping?: EcsMappingSerialized; + ecs_mapping?: ECSMapping; packId?: string; } @@ -78,11 +73,7 @@ const LiveQueryFormComponent: React.FC = ({ [permissions] ); - const hooksForm = useHookForm({ - defaultValues: { - ecs_mapping: [defaultEcsFormData], - }, - }); + const hooksForm = useHookForm(); const { handleSubmit, watch, @@ -91,7 +82,7 @@ const LiveQueryFormComponent: React.FC = ({ clearErrors, getFieldState, register, - formState: { isSubmitting, errors }, + formState: { isSubmitting }, } = hooksForm; const canRunSingleQuery = useMemo( @@ -131,7 +122,7 @@ const LiveQueryFormComponent: React.FC = ({ }, [register]); const queryStatus = useMemo(() => { - if (isError || queryState.invalid) return 'danger'; + if (isError || queryState.error) return 'danger'; if (isLoading) return 'loading'; if (isSuccess) return 'complete'; @@ -144,28 +135,21 @@ const LiveQueryFormComponent: React.FC = ({ ); const onSubmit = useCallback( - async (values: LiveQueryFormFields) => { + (values: LiveQueryFormFields) => { const serializedData = pickBy( { agentSelection: values.agentSelection, saved_query_id: values.savedQueryId, query: values.query, pack_id: values?.packId?.length ? values?.packId[0] : undefined, - ...(values.ecs_mapping - ? { ecs_mapping: convertECSMappingToObject(values.ecs_mapping) } - : {}), + ecs_mapping: values.ecs_mapping, }, (value) => !isEmpty(value) - ); - if (isEmpty(errors)) { - try { - // @ts-expect-error update types - await mutateAsync(serializedData); - // eslint-disable-next-line no-empty - } catch (e) {} - } + ) as unknown as LiveQueryFormFields; + + mutateAsync(serializedData); }, - [errors, mutateAsync] + [mutateAsync] ); const serializedData: SavedQuerySOFormData = useMemo( @@ -287,18 +271,7 @@ const LiveQueryFormComponent: React.FC = ({ if (defaultValue?.query && canRunSingleQuery) { setValue('query', defaultValue.query); setValue('savedQueryId', defaultValue.savedQueryId); - setValue( - 'ecs_mapping', - !isEmpty(defaultValue.ecs_mapping) - ? map(defaultValue.ecs_mapping, (value, key) => ({ - key, - result: { - type: Object.keys(value)[0], - value: Object.values(value)[0], - }, - })) - : [defaultEcsFormData] - ); + setValue('ecs_mapping', defaultValue.ecs_mapping ?? {}); return; } diff --git a/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx b/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx index 2938251e177be..c06555dbb8531 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/live_query_query_field.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { isEmpty, map } from 'lodash'; +import { isEmpty } from 'lodash'; import type { EuiAccordionProps } from '@elastic/eui'; import { EuiCodeBlock, EuiFormRow, EuiAccordion, EuiSpacer } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; @@ -39,11 +39,11 @@ const LiveQueryQueryFieldComponent: React.FC = ({ disabled, handleSubmitForm, }) => { - const formContext = useFormContext(); + const { watch, resetField } = useFormContext(); const [advancedContentState, setAdvancedContentState] = useState('closed'); const permissions = useKibana().services.application.capabilities.osquery; - const queryType = formContext?.watch('queryType', 'query'); + const queryType = watch('queryType', 'query'); const { field: { onChange, value }, @@ -71,31 +71,18 @@ const LiveQueryQueryFieldComponent: React.FC = ({ const handleSavedQueryChange: SavedQueriesDropdownProps['onChange'] = useCallback( (savedQuery) => { if (savedQuery) { - formContext?.setValue('query', savedQuery.query); - formContext?.setValue('savedQueryId', savedQuery.savedQueryId); - if (!isEmpty(savedQuery.ecs_mapping)) { - formContext?.setValue( - 'ecs_mapping', - map(savedQuery.ecs_mapping, (ecsValue, key) => ({ - key, - result: { - type: Object.keys(ecsValue)[0], - value: Object.values(ecsValue)[0] as string, - }, - })) - ); - } else { - formContext?.resetField('ecs_mapping'); - } + resetField('query', { defaultValue: savedQuery.query }); + resetField('savedQueryId', { defaultValue: savedQuery.savedQueryId }); + resetField('ecs_mapping', { defaultValue: savedQuery.ecs_mapping ?? {} }); if (!isEmpty(savedQuery.ecs_mapping)) { setAdvancedContentState('open'); } } else { - formContext?.setValue('savedQueryId', null); + resetField('savedQueryId'); } }, - [formContext] + [resetField] ); const handleToggle = useCallback((isOpen) => { diff --git a/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx b/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx index 38cd6d9cedc3c..39522eba3c3e3 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/pack_queries_status_table.tsx @@ -34,6 +34,7 @@ import type { import { DOCUMENT_FIELD_NAME as RECORDS_FIELD } from '@kbn/lens-plugin/common/constants'; import { FilterStateStore } from '@kbn/es-query'; import styled from 'styled-components'; +import type { ECSMapping } from '../../../common/schemas/common'; import { SECURITY_APP_NAME } from '../../timelines/get_add_to_timeline'; import type { AddToTimelinePayload } from '../../timelines/get_add_to_timeline'; import { PackResultsHeader } from './pack_results_header'; @@ -520,7 +521,7 @@ type PackQueryStatusItem = Partial<{ id: string; query: string; agents: string[]; - ecs_mapping?: unknown; + ecs_mapping?: ECSMapping; version?: string; platform?: string; saved_query_id?: string; diff --git a/x-pack/plugins/osquery/public/live_queries/index.tsx b/x-pack/plugins/osquery/public/live_queries/index.tsx index ba953b4aad6da..986da94c063c1 100644 --- a/x-pack/plugins/osquery/public/live_queries/index.tsx +++ b/x-pack/plugins/osquery/public/live_queries/index.tsx @@ -10,8 +10,8 @@ import { EuiCode, EuiLoadingContent, EuiEmptyPrompt } from '@elastic/eui'; import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import type { ECSMapping } from '../../common/schemas/common'; import type { AddToTimelinePayload } from '../timelines/get_add_to_timeline'; -import type { EcsMappingSerialized } from '../packs/queries/ecs_mapping_editor_field'; import { LiveQueryForm } from './form'; import { useActionResultsPrivileges } from '../action_results/use_action_privileges'; import { OSQUERY_INTEGRATION_NAME } from '../../common'; @@ -25,7 +25,7 @@ interface LiveQueryProps { onSuccess?: () => void; query?: string; savedQueryId?: string; - ecs_mapping?: EcsMappingSerialized; + ecs_mapping?: ECSMapping; agentsField?: boolean; queryField?: boolean; ecsMappingField?: boolean; diff --git a/x-pack/plugins/osquery/public/packs/form/description_field.tsx b/x-pack/plugins/osquery/public/packs/form/description_field.tsx new file mode 100644 index 0000000000000..cdca3749172bd --- /dev/null +++ b/x-pack/plugins/osquery/public/packs/form/description_field.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { useController } from 'react-hook-form'; +import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +interface DescriptionFieldProps { + euiFieldProps?: Record; +} + +const DescriptionFieldComponent: React.FC = ({ euiFieldProps }) => { + const { + field: { onChange, value, name: fieldName }, + fieldState: { error }, + } = useController({ + name: 'description', + defaultValue: '', + }); + + const hasError = useMemo(() => !!error?.message, [error?.message]); + + return ( + + + + ); +}; + +export const DescriptionField = React.memo(DescriptionFieldComponent); diff --git a/x-pack/plugins/osquery/public/packs/form/index.tsx b/x-pack/plugins/osquery/public/packs/form/index.tsx index 51bec779b1f05..594c539c389cf 100644 --- a/x-pack/plugins/osquery/public/packs/form/index.tsx +++ b/x-pack/plugins/osquery/public/packs/form/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { isEmpty, reduce } from 'lodash'; +import { reduce } from 'lodash'; import { EuiFlexGroup, EuiFlexItem, @@ -16,18 +16,10 @@ import { EuiHorizontalRule, } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; -import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import deepEqual from 'fast-deep-equal'; +import { FormProvider, useForm as useHookForm } from 'react-hook-form'; -import { - Form, - useForm, - useFormData, - getUseField, - Field, - FIELD_TYPES, - fieldValidators, -} from '../../shared_imports'; import { useRouterNavigate } from '../../common/lib/kibana'; import { PolicyIdComboBoxField } from './policy_id_combobox_field'; import { QueriesField } from './queries_field'; @@ -36,14 +28,12 @@ import { useAgentPolicies } from '../../agent_policies'; import { useCreatePack } from '../use_create_pack'; import { useUpdatePack } from '../use_update_pack'; import { convertPackQueriesToSO, convertSOQueriesToPack } from './utils'; -import { idSchemaValidation } from '../queries/validations'; import type { PackItem } from '../types'; +import { NameField } from './name_field'; +import { DescriptionField } from './description_field'; +import type { PackQueryFormData } from '../queries/use_pack_query_form'; -const GhostFormField = () => <>; - -const FORM_ID = 'scheduledQueryForm'; - -const CommonUseField = getUseField({ component: Field }); +type PackFormData = Omit & { queries: PackQueryFormData[] }; interface PackFormProps { defaultValue?: PackItem; @@ -70,84 +60,53 @@ const PackFormComponent: React.FC = ({ withRedirect: true, }); - const { form } = useForm({ - id: FORM_ID, - schema: { - name: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.osquery.pack.form.nameFieldLabel', { - defaultMessage: 'Name', - }), - validations: [ - { - validator: idSchemaValidation, - }, - { - validator: fieldValidators.emptyField( - i18n.translate('xpack.osquery.pack.form.nameFieldRequiredErrorMessage', { - defaultMessage: 'Name is a required field', - }) - ), - }, - ], - }, - description: { - type: FIELD_TYPES.TEXT, - label: i18n.translate('xpack.osquery.pack.form.descriptionFieldLabel', { - defaultMessage: 'Description (optional)', - }), - }, - policy_ids: { - defaultValue: [], - type: FIELD_TYPES.COMBO_BOX, - label: i18n.translate('xpack.osquery.pack.form.agentPoliciesFieldLabel', { - defaultMessage: 'Scheduled agent policies (optional)', - }), - helpText: i18n.translate('xpack.osquery.pack.form.agentPoliciesFieldHelpText', { - defaultMessage: 'Queries in this pack are scheduled for agents in the selected policies.', - }), - }, - enabled: { - defaultValue: true, - }, - queries: { - defaultValue: [], - }, - }, - onSubmit: async (formData, isValid) => { - if (isValid) { - try { - if (editMode) { - // @ts-expect-error update types - await updateAsync({ id: defaultValue?.id, ...formData }); - } else { - // @ts-expect-error update types - await createAsync(formData); - } - // eslint-disable-next-line no-empty - } catch (e) {} - } - }, - deserializer: (payload) => ({ - ...payload, - policy_ids: payload.policy_ids ?? [], - queries: convertPackQueriesToSO(payload.queries), - }), - // @ts-expect-error update types - serializer: (payload) => ({ - ...payload, - queries: convertSOQueriesToPack(payload.queries), - }), - defaultValue, + const deserializer = (payload: PackItem) => ({ + ...payload, + policy_ids: payload.policy_ids ?? [], + queries: convertPackQueriesToSO(payload.queries), }); - const { setFieldValue, submit, isSubmitting } = form; + const serializer = (payload: PackFormData) => ({ + ...payload, + queries: convertSOQueriesToPack(payload.queries), + }); - const [{ name: queryName, policy_ids: policyIds }] = useFormData({ - form, - watch: ['name', 'policy_ids'], + const hooksForm = useHookForm({ + defaultValues: defaultValue + ? deserializer(defaultValue) + : { + name: '', + description: '', + policy_ids: [], + enabled: true, + queries: [], + }, }); + const { + handleSubmit, + watch, + formState: { isSubmitting }, + } = hooksForm; + + const onSubmit = useCallback( + async (values: PackFormData) => { + try { + if (editMode && defaultValue?.id) { + await updateAsync({ id: defaultValue?.id, ...serializer(values) }); + } else { + await createAsync(serializer(values)); + } + // eslint-disable-next-line no-empty + } catch (e) {} + }, + [createAsync, defaultValue?.id, editMode, updateAsync] + ); + + const handleSubmitForm = useMemo(() => handleSubmit(onSubmit), [handleSubmit, onSubmit]); + + const { policy_ids: policyIds } = watch(); + const agentCount = useMemo( () => reduce( @@ -162,11 +121,6 @@ const PackFormComponent: React.FC = ({ [policyIds, agentPoliciesById] ); - const handleNameChange = useCallback( - (newName: string) => isEmpty(queryName) && setFieldValue('name', newName), - [queryName, setFieldValue] - ); - const handleSaveClick = useCallback(() => { if (agentCount) { setShowConfirmationModal(true); @@ -174,51 +128,40 @@ const PackFormComponent: React.FC = ({ return; } - submit(); - }, [agentCount, submit]); + handleSubmitForm(); + }, [agentCount, handleSubmitForm]); const handleConfirmConfirmationClick = useCallback(() => { - submit(); + handleSubmitForm(); setShowConfirmationModal(false); - }, [submit]); + }, [handleSubmitForm]); const euiFieldProps = useMemo(() => ({ isDisabled: isReadOnly }), [isReadOnly]); return ( <> -
+ - + - + - + - - - - + +
@@ -272,4 +215,4 @@ const PackFormComponent: React.FC = ({ ); }; -export const PackForm = React.memo(PackFormComponent); +export const PackForm = React.memo(PackFormComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/packs/form/name_field.tsx b/x-pack/plugins/osquery/public/packs/form/name_field.tsx new file mode 100644 index 0000000000000..bb37d0ac5ef7c --- /dev/null +++ b/x-pack/plugins/osquery/public/packs/form/name_field.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { useController } from 'react-hook-form'; +import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +interface NameFieldProps { + euiFieldProps?: Record; +} + +const NameFieldComponent: React.FC = ({ euiFieldProps }) => { + const { + field: { onChange, value, name: fieldName }, + fieldState: { error }, + } = useController({ + name: 'name', + defaultValue: '', + rules: { + pattern: { + value: /^[a-zA-Z0-9-_]+$/, + message: i18n.translate('xpack.osquery.pack.queryFlyoutForm.invalidIdError', { + defaultMessage: 'Characters must be alphanumeric, _, or -', + }), + }, + required: i18n.translate('xpack.osquery.pack.form.nameFieldRequiredErrorMessage', { + defaultMessage: 'Name is a required field', + }), + }, + }); + + const hasError = useMemo(() => !!error?.message, [error?.message]); + + return ( + + + + ); +}; + +export const NameField = React.memo(NameFieldComponent); diff --git a/x-pack/plugins/osquery/public/packs/form/policy_id_combobox_field.tsx b/x-pack/plugins/osquery/public/packs/form/policy_id_combobox_field.tsx index e91ed3bce4ea0..4f17050f9c537 100644 --- a/x-pack/plugins/osquery/public/packs/form/policy_id_combobox_field.tsx +++ b/x-pack/plugins/osquery/public/packs/form/policy_id_combobox_field.tsx @@ -5,16 +5,16 @@ * 2.0. */ -import { reduce } from 'lodash'; +import { castArray, reduce } from 'lodash'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { EuiComboBoxOptionOption } from '@elastic/eui'; -import { EuiFlexGroup, EuiFlexItem, EuiTextColor } from '@elastic/eui'; +import type { EuiComboBoxProps, EuiComboBoxOptionOption } from '@elastic/eui'; +import { EuiComboBox, EuiFormRow, EuiFlexGroup, EuiFlexItem, EuiTextColor } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; - -import type { GetAgentPoliciesResponseItem } from '@kbn/fleet-plugin/common'; -import type { FieldHook } from '../../shared_imports'; -import { ComboBoxField } from '../../shared_imports'; +import deepEqual from 'fast-deep-equal'; +import { i18n } from '@kbn/i18n'; +import { useController } from 'react-hook-form'; +import { useAgentPolicies } from '../../agent_policies'; // Custom styling for drop down list items due to: // 1) the max-width and overflow properties is added to prevent long agent policy @@ -30,43 +30,49 @@ const AgentPolicyDescriptionColumn = styled(EuiFlexItem)` overflow: hidden; `; -type ComboBoxFieldProps = Parameters[0]; - -type PolicyIdComboBoxFieldProps = Pick & { - field: FieldHook; - agentPoliciesById: Record; -}; +interface PolicyIdComboBoxFieldProps { + euiFieldProps?: EuiComboBoxProps; +} const PolicyIdComboBoxFieldComponent: React.FC = ({ euiFieldProps, - field, - agentPoliciesById, }) => { - const { value, setValue } = field; + const { data: { agentPoliciesById } = {} } = useAgentPolicies(); + + const { + field: { onChange, value }, + fieldState: { error }, + } = useController<{ policy_ids: string[] }>({ + name: 'policy_ids', + defaultValue: [], + rules: {}, + }); const options = useMemo( () => - Object.entries(agentPoliciesById).map(([agentPolicyId, agentPolicy]) => ({ + Object.entries(agentPoliciesById ?? {}).map(([agentPolicyId, agentPolicy]) => ({ key: agentPolicyId, label: agentPolicy.name, })), [agentPoliciesById] ); - const selectedOptions = useMemo( - () => - value.map((policyId) => ({ + const selectedOptions = useMemo(() => { + if (agentPoliciesById) { + return castArray(value).map((policyId) => ({ key: policyId, label: agentPoliciesById[policyId]?.name ?? policyId, - })), - [agentPoliciesById, value] - ); + })); + } + + return []; + }, [agentPoliciesById, value]); - const onChange = useCallback( + const handleChange = useCallback( (newOptions: EuiComboBoxOptionOption[]) => { - setValue(newOptions.map((option) => option.key || option.label)); + onChange(newOptions.map((option) => option.key || option.label)); }, - [setValue] + [onChange] ); const renderOption = useCallback( @@ -74,12 +80,12 @@ const PolicyIdComboBoxFieldComponent: React.FC = ({ - {(option.key && agentPoliciesById[option.key]?.name) ?? option.label} + {(option.key && agentPoliciesById?.[option.key]?.name) ?? option.label} - {(option.key && agentPoliciesById[option.key].description) ?? ''} + {(option.key && agentPoliciesById?.[option.key].description) ?? ''} @@ -89,7 +95,7 @@ const PolicyIdComboBoxFieldComponent: React.FC = ({ defaultMessage="{count, plural, one {# agent} other {# agents}} enrolled" // eslint-disable-next-line react-perf/jsx-no-new-object-as-prop values={{ - count: (option.key && agentPoliciesById[option.key]?.agents) ?? 0, + count: (option.key && agentPoliciesById?.[option.key]?.agents) ?? 0, }} /> @@ -101,7 +107,12 @@ const PolicyIdComboBoxFieldComponent: React.FC = ({ const helpText = useMemo(() => { if (!value?.length || !value[0].length || !agentPoliciesById) { - return; + return ( + + ); } const agentCount = reduce( @@ -126,28 +137,31 @@ const PolicyIdComboBoxFieldComponent: React.FC = ({ ); }, [agentPoliciesById, value]); - const mergedEuiFieldProps = useMemo( - () => ({ - onCreateOption: null, - noSuggestions: false, - isClearable: true, - selectedOptions, - options, - renderOption, - onChange, - ...euiFieldProps, - }), - [euiFieldProps, onChange, options, renderOption, selectedOptions] - ); + const hasError = useMemo(() => !!error?.message, [error?.message]); return ( - + error={error?.message} + isInvalid={hasError} + fullWidth + > + + ); }; -export const PolicyIdComboBoxField = React.memo(PolicyIdComboBoxFieldComponent); +export const PolicyIdComboBoxField = React.memo(PolicyIdComboBoxFieldComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/packs/form/queries_field.tsx b/x-pack/plugins/osquery/public/packs/form/queries_field.tsx index 62f5c9c7e7e93..03ab8de199269 100644 --- a/x-pack/plugins/osquery/public/packs/form/queries_field.tsx +++ b/x-pack/plugins/osquery/public/packs/form/queries_field.tsx @@ -5,32 +5,46 @@ * 2.0. */ -import { isEmpty, findIndex, forEach, pullAt, pullAllBy, pickBy } from 'lodash'; +import { isEmpty, findIndex, indexOf, pickBy, uniq, map } from 'lodash'; import type { EuiComboBoxProps } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiSpacer } from '@elastic/eui'; import { produce } from 'immer'; import React, { useCallback, useMemo, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import deepEqual from 'fast-deep-equal'; +import { useController, useFormContext, useWatch, useFieldArray } from 'react-hook-form'; -import type { FieldHook } from '../../shared_imports'; import { PackQueriesTable } from '../pack_queries_table'; import { QueryFlyout } from '../queries/query_flyout'; import { OsqueryPackUploader } from './pack_uploader'; import { getSupportedPlatforms } from '../queries/platforms/helpers'; -import type { PackItem } from '../types'; import type { PackQueryFormData } from '../queries/use_pack_query_form'; interface QueriesFieldProps { - handleNameChange: (name: string) => void; - field: FieldHook; euiFieldProps: EuiComboBoxProps<{}>; } -const QueriesFieldComponent: React.FC = ({ - field, - handleNameChange, - euiFieldProps, -}) => { +const QueriesFieldComponent: React.FC = ({ euiFieldProps }) => { + const { + field: { value: fieldValue }, + } = useController<{ queries: PackQueryFormData[] }, 'queries'>({ + name: 'queries', + defaultValue: [], + rules: {}, + }); + + const { append, remove, update, replace } = useFieldArray({ + name: 'queries', + }); + + const { setValue } = useFormContext(); + const { name: packName } = useWatch(); + + const handleNameChange = useCallback( + (newName: string) => isEmpty(packName) && setValue('name', newName), + [packName, setValue] + ); + const isReadOnly = !!euiFieldProps?.isDisabled; const [showAddQueryFlyout, setShowAddQueryFlyout] = useState(false); const [showEditQueryFlyout, setShowEditQueryFlyout] = useState(-1); @@ -40,61 +54,54 @@ const QueriesFieldComponent: React.FC = ({ const handleHideAddFlyout = useCallback(() => setShowAddQueryFlyout(false), []); const handleHideEditFlyout = useCallback(() => setShowEditQueryFlyout(-1), []); - const { setValue } = field; - const handleDeleteClick = useCallback( (query) => { - const streamIndex = findIndex(field.value, ['id', query.id]); + const streamIndex = findIndex(fieldValue, ['id', query.id]); if (streamIndex > -1) { - setValue( - produce((draft) => { - pullAt(draft, [streamIndex]); - - return draft; - }) - ); + remove(streamIndex); } }, - [field.value, setValue] + [fieldValue, remove] ); const handleEditClick = useCallback( (query) => { - const streamIndex = findIndex(field.value, ['id', query.id]); + const streamIndex = findIndex(fieldValue, ['id', query.id]); setShowEditQueryFlyout(streamIndex); }, - [field.value] + [fieldValue] ); const handleEditQuery = useCallback( (updatedQuery) => new Promise((resolve) => { if (showEditQueryFlyout >= 0) { - setValue( - produce((draft) => { - draft[showEditQueryFlyout].id = updatedQuery.id; - draft[showEditQueryFlyout].interval = updatedQuery.interval; - draft[showEditQueryFlyout].query = updatedQuery.query; + update( + showEditQueryFlyout, + produce({}, (draft: PackQueryFormData) => { + draft.id = updatedQuery.id; + draft.interval = updatedQuery.interval; + draft.query = updatedQuery.query; if (updatedQuery.platform?.length) { - draft[showEditQueryFlyout].platform = updatedQuery.platform; - } else { - delete draft[showEditQueryFlyout].platform; + draft.platform = updatedQuery.platform; } if (updatedQuery.version?.length) { - draft[showEditQueryFlyout].version = updatedQuery.version; - } else { - delete draft[showEditQueryFlyout].version; + draft.version = updatedQuery.version; } if (updatedQuery.ecs_mapping) { - draft[showEditQueryFlyout].ecs_mapping = updatedQuery.ecs_mapping; - } else { - // @ts-expect-error update types - delete draft[showEditQueryFlyout].ecs_mapping; + draft.ecs_mapping = updatedQuery.ecs_mapping; + } + + if (updatedQuery.snapshot === false) { + draft.snapshot = updatedQuery.snapshot; + if (updatedQuery.removed !== undefined) { + draft.removed = updatedQuery.removed; + } } return draft; @@ -105,80 +112,53 @@ const QueriesFieldComponent: React.FC = ({ handleHideEditFlyout(); resolve(); }), - [handleHideEditFlyout, setValue, showEditQueryFlyout] + [handleHideEditFlyout, update, showEditQueryFlyout] ); const handleAddQuery = useCallback( (newQuery) => new Promise((resolve) => { - setValue( - produce((draft) => { - draft.push(newQuery); - - return draft; - }) - ); + append(newQuery); handleHideAddFlyout(); resolve(); }), - [handleHideAddFlyout, setValue] + [handleHideAddFlyout, append] ); const handleDeleteQueries = useCallback(() => { - setValue( - produce((draft) => { - pullAllBy(draft, tableSelectedItems, 'id'); - - return draft; - }) + const idsToRemove = map(tableSelectedItems, (selectedItem) => + indexOf(fieldValue, selectedItem) ); + remove(idsToRemove); setTableSelectedItems([]); - }, [setValue, tableSelectedItems]); + }, [fieldValue, remove, tableSelectedItems]); const handlePackUpload = useCallback( - (parsedContent, packName) => { - setValue( - produce((draft) => { - forEach(parsedContent.queries, (newQuery, newQueryId) => { - draft.push( - // @ts-expect-error update types - pickBy( - { - id: newQueryId, - interval: newQuery.interval ?? parsedContent.interval ?? '3600', - query: newQuery.query, - version: newQuery.version ?? parsedContent.version, - platform: getSupportedPlatforms(newQuery.platform ?? parsedContent.platform), - }, - (value) => !isEmpty(value) - ) - ); - }); - - return draft; - }) + (parsedContent, uploadedPackName) => { + replace( + map(parsedContent.queries, (newQuery, newQueryId) => + pickBy( + { + id: newQueryId, + interval: newQuery.interval ?? parsedContent.interval ?? '3600', + query: newQuery.query, + version: newQuery.version ?? parsedContent.version, + snapshot: newQuery.snapshot ?? parsedContent.snapshot, + removed: newQuery.removed ?? parsedContent.removed, + platform: getSupportedPlatforms(newQuery.platform ?? parsedContent.platform), + }, + (value) => !isEmpty(value) || value === false + ) + ) ); - handleNameChange(packName); + handleNameChange(uploadedPackName); }, - [handleNameChange, setValue] + [handleNameChange, replace] ); - const tableData = useMemo(() => (field.value?.length ? field.value : []), [field.value]); - - const uniqueQueryIds = useMemo( - () => - field.value && field.value.length - ? field.value.reduce((acc, query) => { - if (query?.id) { - acc.push(query.id); - } - - return acc; - }, [] as string[]) - : [], - [field.value] - ); + const tableData = useMemo(() => (fieldValue?.length ? fieldValue : []), [fieldValue]); + const uniqueQueryIds = useMemo(() => uniq(map(fieldValue, 'id')), [fieldValue]); return ( <> @@ -210,7 +190,7 @@ const QueriesFieldComponent: React.FC = ({ )} - {field.value?.length ? ( + {fieldValue?.length ? ( = ({ @@ -242,4 +222,4 @@ const QueriesFieldComponent: React.FC = ({ ); }; -export const QueriesField = React.memo(QueriesFieldComponent); +export const QueriesField = React.memo(QueriesFieldComponent, deepEqual); diff --git a/x-pack/plugins/osquery/public/packs/form/utils.ts b/x-pack/plugins/osquery/public/packs/form/utils.ts index 446172c1cd5ce..e04db1ed5b237 100644 --- a/x-pack/plugins/osquery/public/packs/form/utils.ts +++ b/x-pack/plugins/osquery/public/packs/form/utils.ts @@ -6,25 +6,31 @@ */ import { pick, reduce } from 'lodash'; +import type { PackQueryFormData } from '../queries/use_pack_query_form'; -// @ts-expect-error update types -export const convertPackQueriesToSO = (queries) => +export const convertPackQueriesToSO = (queries: Record>) => reduce( queries, (acc, value, key) => { acc.push({ - // @ts-expect-error update types id: key, - ...pick(value, ['query', 'interval', 'platform', 'version', 'ecs_mapping']), + ...pick(value, [ + 'query', + 'interval', + 'snapshot', + 'removed', + 'platform', + 'version', + 'ecs_mapping', + ]), }); return acc; }, - [] + [] as PackQueryFormData[] ); -// @ts-expect-error update types -export const convertSOQueriesToPack = (queries) => +export const convertSOQueriesToPack = (queries: PackQueryFormData[]) => reduce( queries, (acc, { id: queryId, ...query }) => { @@ -32,6 +38,5 @@ export const convertSOQueriesToPack = (queries) => return acc; }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - {} as Record + {} as Record> ); diff --git a/x-pack/plugins/osquery/public/packs/pack_queries_table.tsx b/x-pack/plugins/osquery/public/packs/pack_queries_table.tsx index 4bf2c96b6a649..60569ebaf184a 100644 --- a/x-pack/plugins/osquery/public/packs/pack_queries_table.tsx +++ b/x-pack/plugins/osquery/public/packs/pack_queries_table.tsx @@ -10,16 +10,15 @@ import { EuiBasicTable, EuiCodeBlock, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { PlatformIcons } from './queries/platforms'; -import type { PackItem } from './types'; import type { PackQueryFormData } from './queries/use_pack_query_form'; export interface PackQueriesTableProps { - data: PackItem['queries']; + data: PackQueryFormData[]; isReadOnly?: boolean; onDeleteClick?: (item: PackQueryFormData) => void; onEditClick?: (item: PackQueryFormData) => void; - selectedItems?: PackItem['queries']; - setSelectedItems?: (selection: PackItem['queries']) => void; + selectedItems?: PackQueryFormData[]; + setSelectedItems?: (selection: PackQueryFormData[]) => void; } const PackQueriesTableComponent: React.FC = ({ diff --git a/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx b/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx index f0da49b7c216b..588c681ea5dfb 100644 --- a/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/ecs_mapping_editor_field.tsx @@ -6,6 +6,7 @@ */ import { + last, castArray, each, isEmpty, @@ -17,6 +18,7 @@ import { reduce, trim, get, + reject, } from 'lodash'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import type { EuiComboBoxProps, EuiComboBoxOptionOption } from '@elastic/eui'; @@ -38,32 +40,21 @@ import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; import deepEqual from 'fast-deep-equal'; -import { useController, useFieldArray, useFormContext, useWatch } from 'react-hook-form'; -import type { FormField } from '../../form/types'; +import type { InternalFieldErrors, UseFieldArrayRemove, UseFormReturn } from 'react-hook-form'; +import { useForm, useController, useFieldArray, useFormContext } from 'react-hook-form'; +import type { ECSMappingArray, ECSMapping } from '../../../common/schemas/common/utils'; +import { + convertECSMappingToArray, + convertECSMappingToObject, +} from '../../../common/schemas/common/utils'; import ECSSchema from '../../common/schemas/ecs/v8.4.0.json'; import osquerySchema from '../../common/schemas/osquery/v5.4.0.json'; import { FieldIcon } from '../../common/lib/kibana'; -import type { FormArrayField } from '../../shared_imports'; import { OsqueryIcon } from '../../components/osquery_icon'; import { removeMultilines } from '../../../common/utils/build_query/remove_multilines'; -import { prepareEcsFieldsToValidate } from '../../common/helpers'; - -export interface EcsMappingFormField { - key: string; - result: { - type: string; - value: string; - }; -} -export type EcsMappingSerialized = Record< - string, - { - field?: string; - value?: string; - } ->; +export type ECSMappingFormReturn = UseFormReturn<{ ecsMappingArray: ECSMappingArray }>; const typeMap = { binary: 'binary', @@ -148,8 +139,11 @@ const ECSSchemaOptions = ECSSchema.map((ecs) => ({ type ECSSchemaOption = typeof ECSSchemaOptions[0]; -interface ECSComboboxFieldProps extends FormField { +interface ECSComboboxFieldProps { euiFieldProps: EuiComboBoxProps; + control: ECSMappingFormReturn['control']; + watch: ECSMappingFormReturn['watch']; + index: number; idAria?: string; error?: string; } @@ -157,23 +151,43 @@ interface ECSComboboxFieldProps extends FormField { const ECSComboboxFieldComponent: React.FC = ({ euiFieldProps = {}, idAria, - onChange, - value, - error, + index, + watch, + control, }) => { + const { ecsMappingArray } = watch(); + const ecsCurrentMapping = get(ecsMappingArray, `[${index}].result.value`); + + const ecsFieldValidator = useCallback( + (value: string) => + !value?.length && ecsCurrentMapping?.length + ? i18n.translate('xpack.osquery.pack.queryFlyoutForm.ecsFieldRequiredErrorMessage', { + defaultMessage: 'ECS field is required.', + }) + : undefined, + [ecsCurrentMapping?.length] + ); + + const { field: ECSField, fieldState: ECSFieldState } = useController({ + control, + name: `ecsMappingArray.${index}.key`, + rules: { + validate: ecsFieldValidator, + }, + defaultValue: '', + }); + const [selectedOptions, setSelected] = useState>>( [] ); const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); - const { ecs_mapping: watchedEcsMapping } = useWatch() as unknown as { - ecs_mapping: EcsMappingFormField[]; - }; + const { ecsMappingArray: watchedEcsMapping } = watch(); const handleChange = useCallback( (newSelectedOptions) => { setSelected(newSelectedOptions); - onChange(newSelectedOptions[0]?.label ?? ''); + ECSField.onChange(newSelectedOptions[0]?.label ?? ''); }, - [onChange] + [ECSField] ); // TODO: Create own component for this. @@ -243,22 +257,22 @@ const ECSComboboxFieldComponent: React.FC = ({ useEffect(() => { // @ts-expect-error update types setSelected(() => { - if (!value?.length) return []; + if (!ECSField.value?.length) return []; - const selectedOption = find(ECSSchemaOptions, ['label', value]); + const selectedOption = find(ECSSchemaOptions, ['label', ECSField.value]); return selectedOption ? [selectedOption] : [ { - label: value, + label: ECSField.value, value: { - value, + value: ECSField.value, }, }, ]; }); - }, [value]); + }, [ECSField.value]); return ( = ({ defaultMessage: 'ECS field', })} helpText={helpText} - error={error} - isInvalid={!!error} + error={ECSFieldState.error?.message} + isInvalid={!!ECSFieldState.error?.message?.length} fullWidth describedByIds={describedByIds} isDisabled={euiFieldProps.isDisabled} @@ -276,6 +290,7 @@ const ECSComboboxFieldComponent: React.FC = ({ prepend={prepend} fullWidth singleSelection={SINGLE_SELECTION} + error={ECSFieldState.error?.message} // @ts-expect-error update types options={availableECSSchemaOptions} selectedOptions={selectedOptions} @@ -290,7 +305,7 @@ const ECSComboboxFieldComponent: React.FC = ({ ); }; -export const ECSComboboxField = React.memo(ECSComboboxFieldComponent); +export const ECSComboboxField = React.memo(ECSComboboxFieldComponent, deepEqual); const OSQUERY_COLUMN_VALUE_TYPE_OPTIONS = [ { @@ -337,8 +352,10 @@ const EMPTY_ARRAY: EuiComboBoxOptionOption[] = []; interface OsqueryColumnFieldProps { euiFieldProps: EuiComboBoxProps; - item: EcsMappingFormField; index: number; + control: ECSMappingFormReturn['control']; + watch: ECSMappingFormReturn['watch']; + trigger: ECSMappingFormReturn['trigger']; idAria?: string; isLastItem: boolean; } @@ -346,59 +363,64 @@ interface OsqueryColumnFieldProps { const OsqueryColumnFieldComponent: React.FC = ({ euiFieldProps, idAria, - item, index, isLastItem, + control, + watch, + trigger, }) => { - const osqueryResultFieldValidator = ( - value: string, - ecsMappingFormData: EcsMappingFormField[] - ): string | undefined => { - const currentMapping = ecsMappingFormData[index]; - - if (!value.length && currentMapping.key.length) { - return i18n.translate( - 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage', - { - defaultMessage: 'Value field is required.', - } - ); - } - - if (!value.length || currentMapping.result.type !== 'field') return; + const { ecsMappingArray } = watch(); - const osqueryColumnExists = find(euiFieldProps.options, [ - 'label', - isArray(value) ? value[0] : value, - ]); + const osqueryResultFieldValidator = useCallback( + (value: string | string[]): string | undefined => { + const currentMapping = ecsMappingArray && ecsMappingArray[index]; - return !osqueryColumnExists - ? i18n.translate( - 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldValueMissingErrorMessage', + if (!value?.length && currentMapping?.key?.length) { + return i18n.translate( + 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldRequiredErrorMessage', { - defaultMessage: 'The current query does not return a {columnName} field', - values: { - columnName: value, - }, + defaultMessage: 'Value field is required.', } - ) - : undefined; - }; + ); + } - const { setValue } = useFormContext(); - const { ecs_mapping: watchedEcsMapping } = useWatch() as unknown as { - ecs_mapping: EcsMappingFormField[]; - }; + if (!value?.length || currentMapping?.result?.type !== 'field') return; + + const osqueryColumnExists = find(euiFieldProps.options, [ + 'label', + isArray(value) ? value[0] : value, + ]); + + return !osqueryColumnExists + ? i18n.translate( + 'xpack.osquery.pack.queryFlyoutForm.osqueryResultFieldValueMissingErrorMessage', + { + defaultMessage: 'The current query does not return a {columnName} field', + values: { + columnName: isArray(value) ? value[0] : value, + }, + } + ) + : undefined; + }, + [ecsMappingArray, euiFieldProps.options, index] + ); + + const { field: resultTypeField } = useController({ + control, + name: `ecsMappingArray.${index}.result.type`, + defaultValue: OSQUERY_COLUMN_VALUE_TYPE_OPTIONS[0].value, + }); const { field: resultField, fieldState: resultFieldState } = useController({ - name: `ecs_mapping.${index}.result.value`, + control, + name: `ecsMappingArray.${index}.result.value`, rules: { - validate: (data) => osqueryResultFieldValidator(data, watchedEcsMapping), + validate: osqueryResultFieldValidator, }, defaultValue: '', }); - const itemPath = `ecs_mapping.${index}`; - const resultValue = item.result; + const inputRef = useRef(); const [selectedOptions, setSelected] = useState([]); const describedByIds = useMemo(() => (idAria ? [idAria] : []), [idAria]); @@ -438,8 +460,8 @@ const OsqueryColumnFieldComponent: React.FC = ({ ); const isSingleSelection = useMemo(() => { - const ecsData = get(watchedEcsMapping, `${index}`); - if (ecsData?.key?.length && item.result.type === 'value') { + const ecsData = get(ecsMappingArray, `${index}`); + if (ecsData?.key?.length && resultTypeField.value === 'value') { const ecsKeySchemaOption = find(ECSSchemaOptions, ['label', ecsData?.key]); return ecsKeySchemaOption?.value?.normalization !== 'array'; @@ -450,19 +472,16 @@ const OsqueryColumnFieldComponent: React.FC = ({ } return !!ecsData?.key?.length; - }, [index, isLastItem, item.result.type, watchedEcsMapping]); + }, [ecsMappingArray, index, isLastItem, resultTypeField.value]); const onTypeChange = useCallback( (newType) => { - if (newType !== item.result.type) { - setValue(`${itemPath}.result.type`, newType); - setValue( - `${itemPath}.result.value`, - newType === 'value' && isSingleSelection === false ? [] : '' - ); + if (newType !== resultTypeField.value) { + resultTypeField.onChange(newType); + resultField.onChange(newType === 'value' && isSingleSelection === false ? [] : ''); } }, - [isSingleSelection, item.result.type, itemPath, setValue] + [isSingleSelection, resultField, resultTypeField] ); const handleCreateOption = useCallback( @@ -472,19 +491,19 @@ const OsqueryColumnFieldComponent: React.FC = ({ if (!trimmedNewOption.length) return; if (isSingleSelection === false) { - setValue(`${itemPath}.result.value`, [trimmedNewOption]); - if (item.result.value.length) { - setValue(`${itemPath}.result.value`, [...castArray(resultValue.value), trimmedNewOption]); + resultField.onChange([trimmedNewOption]); + if (resultField.value?.length) { + resultField.onChange([...castArray(resultField.value), trimmedNewOption]); } else { - setValue(`${itemPath}.result.value`, [trimmedNewOption]); + resultField.onChange([trimmedNewOption]); } inputRef.current?.blur(); } else { - setValue(`${itemPath}.result.value`, trimmedNewOption); + resultField.onChange(trimmedNewOption); } }, - [isSingleSelection, item.result.value.length, itemPath, resultValue.value, setValue] + [isSingleSelection, resultField] ); const Prepend = useMemo( @@ -492,7 +511,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ = ({ onChange={onTypeChange} /> ), - [euiFieldProps.isDisabled, item.result.type, onTypeChange] + [euiFieldProps.isDisabled, onTypeChange, resultTypeField.value] ); useEffect(() => { - if (isSingleSelection && isArray(resultValue.value)) { - setValue(`${itemPath}.result.value`, resultValue.value.join(' ')); + if (isSingleSelection && isArray(resultField.value)) { + resultField.onChange(resultField.value.join(' ')); } - if (!isSingleSelection && !isArray(resultValue.value)) { - const value = resultValue.value.length ? [resultValue.value] : []; - setValue(`${itemPath}.result.value`, value); + if (!isSingleSelection && !isArray(resultField.value)) { + const value = resultField.value.length ? [resultField.value] : []; + resultField.onChange(value); } - }, [index, isSingleSelection, itemPath, resultValue, resultValue.value, setValue]); + }, [index, isSingleSelection, resultField, resultField.value]); useEffect(() => { // @ts-expect-error hard to type to satisfy TS, but it represents proper types setSelected((_: OsquerySchemaOption[]): OsquerySchemaOption[] | Array<{ label: string }> => { - if (!resultValue.value.length) return []; + if (!resultField.value?.length) return []; // Static array values - if (isArray(resultValue.value)) { - return resultValue.value.map((value) => ({ label: value })) as OsquerySchemaOption[]; + if (isArray(resultField.value)) { + return resultField.value.map((value) => ({ label: value })) as OsquerySchemaOption[]; } - const selectedOption = find(euiFieldProps?.options, ['label', resultValue.value]) as + const selectedOption = find(euiFieldProps?.options, ['label', resultField.value]) as | OsquerySchemaOption | undefined; - return selectedOption ? [selectedOption] : [{ label: resultValue.value }]; + return selectedOption ? [selectedOption] : [{ label: resultField.value }]; }); - }, [euiFieldProps?.options, setSelected, resultValue.value]); + }, [euiFieldProps?.options, setSelected, resultField.value]); + + useEffect(() => { + trigger(`ecsMappingArray.${index}.key`); + }, [resultField.value, trigger, index]); return ( = ({ {Prepend} { @@ -566,7 +586,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ rowHeight={32} isClearable singleSelection={isSingleSelection ? SINGLE_SELECTION : false} - options={(item.result.type === 'field' && euiFieldProps.options) || EMPTY_ARRAY} + options={(resultTypeField.value === 'field' && euiFieldProps.options) || EMPTY_ARRAY} idAria={idAria} helpText={selectedOptions[0]?.value?.description} {...euiFieldProps} @@ -577,7 +597,7 @@ const OsqueryColumnFieldComponent: React.FC = ({ ); }; -export const OsqueryColumnField = React.memo(OsqueryColumnFieldComponent); +export const OsqueryColumnField = React.memo(OsqueryColumnFieldComponent, deepEqual); export interface ECSMappingEditorFieldProps { euiFieldProps?: EuiComboBoxProps<{}>; @@ -586,11 +606,12 @@ export interface ECSMappingEditorFieldProps { interface ECSMappingEditorFormProps { isDisabled?: boolean; osquerySchemaOptions: OsquerySchemaOption[]; - item: EcsMappingFormField; index: number; isLastItem: boolean; - onAppend: (ecs_mapping: EcsMappingFormField[]) => void; - onDelete?: FormArrayField['removeItem']; + control: ECSMappingFormReturn['control']; + watch: ECSMappingFormReturn['watch']; + trigger: ECSMappingFormReturn['trigger']; + onDelete?: UseFieldArrayRemove; } export const defaultEcsFormData = { @@ -604,34 +625,13 @@ export const defaultEcsFormData = { export const ECSMappingEditorForm: React.FC = ({ isDisabled, osquerySchemaOptions, - item, isLastItem, index, onDelete, + control, + watch, + trigger, }) => { - const ecsFieldValidator = (value: string, ecsMapping: EcsMappingFormField[]) => { - const ecsCurrentMapping = ecsMapping[index].result.value; - - return !value.length && ecsCurrentMapping.length - ? i18n.translate('xpack.osquery.pack.queryFlyoutForm.ecsFieldRequiredErrorMessage', { - defaultMessage: 'ECS field is required.', - }) - : undefined; - }; - - const { ecs_mapping: ecsMapping } = useWatch() as unknown as { - ecs_mapping: EcsMappingFormField[]; - }; - const { field: ECSField, fieldState: ECSFieldState } = useController({ - name: `ecs_mapping.${index}.key`, - rules: { - validate: (value: string) => ecsFieldValidator(value, ecsMapping), - }, - defaultValue: '', - }); - - const ecsComboBoxEuiFieldProps = useMemo(() => ({ isDisabled }), [isDisabled]); - const handleDeleteClick = useCallback(() => { if (onDelete) { onDelete(index); @@ -645,12 +645,13 @@ export const ECSMappingEditorForm: React.FC = ({ @@ -664,7 +665,9 @@ export const ECSMappingEditorForm: React.FC = ({ { - const { trigger } = useFormContext(); - const { fields, append, remove } = useFieldArray<{ ecs_mapping: EcsMappingFormField[] }>({ - name: 'ecs_mapping', - }); +export const ECSMappingEditorField = React.memo(({ euiFieldProps }: ECSMappingEditorFieldProps) => { + const { + setError, + clearErrors, + watch: watchRoot, + register: registerRoot, + setValue: setValueRoot, + formState: { errors: errorsRoot }, + } = useFormContext<{ query: string; ecs_mapping: ECSMapping }>(); - const itemsList = useRef>([]); - const [osquerySchemaOptions, setOsquerySchemaOptions] = useState([]); - const { query, ...formData } = useWatch() as unknown as { - query: string; - ecs_mapping: EcsMappingFormField[]; - }; - - useEffect(() => { - // Additional 'suspended' validation of osquery ecs fields. fieldsToValidateOnChange doesn't work because it happens before the osquerySchema gets updated. - const fieldsToValidate = prepareEcsFieldsToValidate(fields); - // it is always at least 2 - empty fields - if (fieldsToValidate.length > 2) { - setTimeout(() => trigger('ecs_mapping'), 0); + useEffect(() => { + registerRoot('ecs_mapping'); + }, [registerRoot]); + + const [query, ecsMapping] = watchRoot(['query', 'ecs_mapping'], { ecs_mapping: {} }); + const { control, trigger, watch, formState, resetField, getFieldState } = useForm<{ + ecsMappingArray: ECSMappingArray; + }>({ + mode: 'all', + shouldUnregister: true, + defaultValues: { + ecsMappingArray: !isEmpty(convertECSMappingToArray(ecsMapping)) + ? [...convertECSMappingToArray(ecsMapping), defaultEcsFormData] + : [defaultEcsFormData], + }, + }); + const { fields, append, remove, replace } = useFieldArray({ + control, + name: 'ecsMappingArray', + }); + + const formValue = watch(); + const ecsMappingArrayState = getFieldState('ecsMappingArray', formState); + const [osquerySchemaOptions, setOsquerySchemaOptions] = useState([]); + + useEffect(() => { + const subscription = watchRoot((data, payload) => { + if (payload.name === 'ecs_mapping') { + const parsedMapping = convertECSMappingToObject(formValue.ecsMappingArray); + if (!deepEqual(data.ecs_mapping, parsedMapping)) { + resetField('ecsMappingArray', { + defaultValue: [...convertECSMappingToArray(data.ecs_mapping), defaultEcsFormData], + }); + replace([...convertECSMappingToArray(data.ecs_mapping), defaultEcsFormData]); + } } - }, [fields, query, trigger]); + }); + + return () => subscription.unsubscribe(); + }, [watchRoot, ecsMapping, replace, resetField, formValue.ecsMappingArray]); - useEffect(() => { - if (!query?.length) { - return; + useEffect(() => { + const subscription = watch((data, payload) => { + if (data?.ecsMappingArray) { + const lastEcsIndex = data?.ecsMappingArray?.length - 1; + if (payload.name?.startsWith(`ecsMappingArray.${lastEcsIndex}.`)) { + const lastEcs = last(data.ecsMappingArray); + if (lastEcs?.key?.length && lastEcs?.result?.value?.length) { + append(defaultEcsFormData); + } + } } + }); + + return () => subscription.unsubscribe(); + }, [formValue, append, watch]); + + useEffect(() => { + if (!query?.length) { + return; + } + + const oneLineQuery = removeMultilines(query); - const oneLineQuery = removeMultilines(query); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let ast: Record | undefined; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let ast: Record | undefined; + try { + ast = sqliteParser(oneLineQuery)?.statement?.[0]; + } catch (e) { + return; + } - try { - ast = sqliteParser(oneLineQuery)?.statement?.[0]; - } catch (e) { - return; + const astOsqueryTables: Record< + string, + { + columns: OsqueryColumn[]; + order: number; } + > = + reduce( + ast, + (acc, data) => { + // select * from uptime + if (data?.type === 'identifier' && data?.variant === 'table') { + const osqueryTable = find(osquerySchema, ['name', data.name]); + + if (osqueryTable) { + acc[data.alias || data.name] = { + columns: osqueryTable.columns, + order: Object.keys(acc).length, + }; + } + } - const astOsqueryTables: Record< - string, - { - columns: OsqueryColumn[]; - order: number; - } - > = - reduce( - ast, - (acc, data) => { - // select * from uptime - if (data?.type === 'identifier' && data?.variant === 'table') { - const osqueryTable = find(osquerySchema, ['name', data.name]); + // select * from uptime, routes + if (data?.type === 'map' && data?.variant === 'join') { + if (data?.source?.type === 'identifier' && data?.source?.variant === 'table') { + const osqueryTable = find(osquerySchema, ['name', data?.source?.name]); if (osqueryTable) { - acc[data.alias || data.name] = { + acc[data?.source?.alias || data?.source?.name] = { columns: osqueryTable.columns, order: Object.keys(acc).length, }; } } - // select * from uptime, routes - if (data?.type === 'map' && data?.variant === 'join') { - if (data?.source?.type === 'identifier' && data?.source?.variant === 'table') { - const osqueryTable = find(osquerySchema, ['name', data?.source?.name]); + if (data?.source?.type === 'statement' && data?.source?.variant === 'compound') { + if ( + data?.source?.statement.from.type === 'identifier' && + data?.source?.statement.from.variant === 'table' + ) { + const osqueryTable = find(osquerySchema, [ + 'name', + data?.source?.statement.from.name, + ]); if (osqueryTable) { - acc[data?.source?.alias || data?.source?.name] = { + acc[data?.source?.statement.from.alias || data?.source?.statement.from.name] = { columns: osqueryTable.columns, order: Object.keys(acc).length, }; } } + } - if (data?.source?.type === 'statement' && data?.source?.variant === 'compound') { - if ( - data?.source?.statement.from.type === 'identifier' && - data?.source?.statement.from.variant === 'table' - ) { - const osqueryTable = find(osquerySchema, [ - 'name', - data?.source?.statement.from.name, - ]); - - if (osqueryTable) { - acc[data?.source?.statement.from.alias || data?.source?.statement.from.name] = { - columns: osqueryTable.columns, - order: Object.keys(acc).length, - }; - } - } - } - - each( - data?.map, - (mapValue: { - type: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - source: { type: string; variant: string; name: any | string; alias: any }; - }) => { - if (mapValue?.type === 'join') { - if ( - mapValue?.source?.type === 'identifier' && - mapValue?.source?.variant === 'table' - ) { - const osqueryTable = find(osquerySchema, ['name', mapValue?.source?.name]); - - if (osqueryTable) { - acc[mapValue?.source?.alias || mapValue?.source?.name] = { - columns: osqueryTable.columns, - order: Object.keys(acc).length, - }; - } + each( + data?.map, + (mapValue: { + type: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + source: { type: string; variant: string; name: any | string; alias: any }; + }) => { + if (mapValue?.type === 'join') { + if ( + mapValue?.source?.type === 'identifier' && + mapValue?.source?.variant === 'table' + ) { + const osqueryTable = find(osquerySchema, ['name', mapValue?.source?.name]); + + if (osqueryTable) { + acc[mapValue?.source?.alias || mapValue?.source?.name] = { + columns: osqueryTable.columns, + order: Object.keys(acc).length, + }; } } } - ); - } + } + ); + } - return acc; - }, - {} as Record< - string, - { - columns: OsqueryColumn[]; - order: number; - } - > - ) ?? {}; + return acc; + }, + {} as Record< + string, + { + columns: OsqueryColumn[]; + order: number; + } + > + ) ?? {}; - // Table doesn't exist in osquery schema - if (isEmpty(astOsqueryTables)) { - return; - } + // Table doesn't exist in osquery schema + if (isEmpty(astOsqueryTables)) { + return; + } - const suggestions = isArray(ast?.result) - ? ast?.result - ?.map((selectItem: { type: string; name: string; alias?: string }) => { - if (selectItem.type === 'identifier') { - /* + const suggestions = isArray(ast?.result) + ? ast?.result + ?.map((selectItem: { type: string; name: string; alias?: string }) => { + if (selectItem.type === 'identifier') { + /* select * from routes, uptime; */ - if (ast?.result.length === 1 && selectItem.name === '*') { - return reduce( - astOsqueryTables, - (acc, { columns: osqueryColumns, order: tableOrder }, table) => { - acc.push( - ...osqueryColumns.map((osqueryColumn) => ({ - label: osqueryColumn.name, - value: { - name: osqueryColumn.name, - description: osqueryColumn.description, - table, - tableOrder, - suggestion_label: osqueryColumn.name, - }, - })) - ); - - return acc; - }, - [] as OsquerySchemaOption[] - ); - } - - /* - select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid; - */ - - const [table, column] = selectItem.name.includes('.') - ? selectItem.name?.split('.') - : [Object.keys(astOsqueryTables)[0], selectItem.name]; - - if (column === '*' && astOsqueryTables[table]) { - const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table]; - - return osqueryColumns.map((osqueryColumn) => ({ - label: osqueryColumn.name, - value: { - name: osqueryColumn.name, - description: osqueryColumn.description, - table, - tableOrder, - suggestion_label: `${osqueryColumn.name}`, - }, - })); - } - - if (astOsqueryTables[table]) { - const osqueryColumn = find(astOsqueryTables[table].columns, ['name', column]); - - if (osqueryColumn) { - const label = selectItem.alias ?? column; - - return [ - { - label, + if (ast?.result.length === 1 && selectItem.name === '*') { + return reduce( + astOsqueryTables, + (acc, { columns: osqueryColumns, order: tableOrder }, table) => { + acc.push( + ...osqueryColumns.map((osqueryColumn) => ({ + label: osqueryColumn.name, value: { name: osqueryColumn.name, description: osqueryColumn.description, table, - tableOrder: astOsqueryTables[table].order, - suggestion_label: `${label}`, + tableOrder, + suggestion_label: osqueryColumn.name, }, + })) + ); + + return acc; + }, + [] as OsquerySchemaOption[] + ); + } + + /* + select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid; + */ + + const [table, column] = selectItem.name.includes('.') + ? selectItem.name?.split('.') + : [Object.keys(astOsqueryTables)[0], selectItem.name]; + + if (column === '*' && astOsqueryTables[table]) { + const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table]; + + return osqueryColumns.map((osqueryColumn) => ({ + label: osqueryColumn.name, + value: { + name: osqueryColumn.name, + description: osqueryColumn.description, + table, + tableOrder, + suggestion_label: `${osqueryColumn.name}`, + }, + })); + } + + if (astOsqueryTables[table]) { + const osqueryColumn = find(astOsqueryTables[table].columns, ['name', column]); + + if (osqueryColumn) { + const label = selectItem.alias ?? column; + + return [ + { + label, + value: { + name: osqueryColumn.name, + description: osqueryColumn.description, + table, + tableOrder: astOsqueryTables[table].order, + suggestion_label: `${label}`, }, - ]; - } + }, + ]; } } + } - /* + /* SELECT pid, uid, name, ROUND(( (user_time + system_time) / (cpu_time.tsb - cpu_time.itsb) ) * 100, 2) AS percentage @@ -945,100 +992,105 @@ export const ECSMappingEditorField = React.memo( LIMIT 5; */ - if (selectItem.type === 'function' && selectItem.alias) { - return [ - { - label: selectItem.alias, - value: { - name: selectItem.alias, - description: '', - table: '', - tableOrder: -1, - suggestion_label: selectItem.alias, - }, + if (selectItem.type === 'function' && selectItem.alias) { + return [ + { + label: selectItem.alias, + value: { + name: selectItem.alias, + description: '', + table: '', + tableOrder: -1, + suggestion_label: selectItem.alias, }, - ]; - } + }, + ]; + } - return []; - }) - .flat() - : []; + return []; + }) + .flat() + : []; - // Remove column duplicates by keeping the column from the table that appears last in the query - const newOptions = sortedUniqBy( - orderBy(suggestions, ['value.suggestion_label', 'value.tableOrder'], ['asc', 'desc']), - 'label' - ); - setOsquerySchemaOptions((prevValue) => - !deepEqual(prevValue, newOptions) ? newOptions : prevValue - ); - }, [query]); + // Remove column duplicates by keeping the column from the table that appears last in the query + const newOptions = sortedUniqBy( + orderBy(suggestions, ['value.suggestion_label', 'value.tableOrder'], ['asc', 'desc']), + 'label' + ); + setOsquerySchemaOptions((prevValue) => + !deepEqual(prevValue, newOptions) ? newOptions : prevValue + ); + }, [query]); - useEffect(() => { - const ecsList = formData?.ecs_mapping; - const lastEcs = formData?.ecs_mapping?.[itemsList?.current.length - 1]; + useEffect(() => { + const parsedMapping = convertECSMappingToObject(formValue.ecsMappingArray); + if (ecsMappingArrayState.isDirty && !deepEqual(parsedMapping, ecsMapping)) { + setValueRoot('ecs_mapping', parsedMapping, { + shouldTouch: true, + }); + } + }, [setValueRoot, formValue, ecsMappingArrayState.isDirty, ecsMapping]); - // we skip appending on remove - if (itemsList?.current?.length < ecsList?.length) { - return; + useEffect(() => { + if (!formState.isValid) { + const nonEmptyErrors = reject(ecsMappingArrayState.error, isEmpty) as InternalFieldErrors[]; + if (nonEmptyErrors.length) { + setError('ecs_mapping', { + type: nonEmptyErrors[0].key?.type ?? 'custom', + message: nonEmptyErrors[0].key?.message ?? '', + }); } + } else { + clearErrors('ecs_mapping'); + } + }, [ + errorsRoot, + clearErrors, + formState.isValid, + formState.errors, + setError, + ecsMappingArrayState.error, + ]); - // list contains ecs already, and the last item has values provided - if ( - (ecsList?.length === itemsList.current.length && - lastEcs?.key?.length && - lastEcs?.result?.value?.length) || - !fields?.length - ) { - return append(defaultEcsFormData); - } - }, [append, fields, formData]); - - return ( - <> - - - -
- -
-
- + return ( + <> + + + +
- - - - - - {fields.map((item, index, array) => { - itemsList.current = array; - - return ( -
- -
- ); - })} - - ); - }, - (prevProps, nextProps) => deepEqual(prevProps.euiFieldProps, nextProps.euiFieldProps) -); +
+
+ + + +
+
+ + + {fields.map((item, index, array) => ( +
+ +
+ ))} + + ); +}); // eslint-disable-next-line import/no-default-export export default ECSMappingEditorField; diff --git a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx index ae3030d75154b..d709b4f639e6d 100644 --- a/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/query_flyout.tsx @@ -22,10 +22,8 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { FormProvider } from 'react-hook-form'; -import { isEmpty } from 'lodash'; -import { QueryIdField, IntervalField } from '../../form'; -import { defaultEcsFormData } from './ecs_mapping_editor_field'; -import { convertECSMappingToFormValue } from '../../../common/schemas/common/utils'; +import { DEFAULT_PLATFORM } from '../../../common/constants'; +import { QueryIdField, IntervalField, VersionField, ResultsTypeField } from '../../form'; import { CodeEditorField } from '../../saved_queries/form/code_editor_field'; import { PlatformCheckBoxGroupField } from './platform_checkbox_group_field'; import { ALL_OSQUERY_VERSIONS_OPTIONS } from './constants'; @@ -38,7 +36,6 @@ import { usePackQueryForm } from './use_pack_query_form'; import { SavedQueriesDropdown } from '../../saved_queries/saved_queries_dropdown'; import { ECSMappingEditorField } from './lazy_ecs_mapping_editor_field'; import { useKibana } from '../../common/lib/kibana'; -import { VersionField } from '../../form'; interface QueryFlyoutProps { uniqueQueryIds: string[]; @@ -63,8 +60,7 @@ const QueryFlyoutComponent: React.FC = ({ const { handleSubmit, formState: { isSubmitting }, - setValue, - clearErrors, + resetField, } = hooksForm; const onSubmit = (payload: PackQueryFormData) => { const serializedData: PackSOQueryFormData = serializer(payload); @@ -75,22 +71,19 @@ const QueryFlyoutComponent: React.FC = ({ const handleSetQueryValue = useCallback( (savedQuery) => { if (savedQuery) { - clearErrors('id'); - setValue('id', savedQuery.id); - setValue('query', savedQuery.query); - // setValue('description', savedQuery.description); // TODO do we need it? - setValue('platform', savedQuery.platform ? savedQuery.platform : 'linux,windows,darwin'); - setValue('version', savedQuery.version ? [savedQuery.version] : []); - setValue('interval', savedQuery.interval); - setValue( - 'ecs_mapping', - !isEmpty(savedQuery.ecs_mapping) - ? convertECSMappingToFormValue(savedQuery.ecs_mapping) - : [defaultEcsFormData] - ); + resetField('id', { defaultValue: savedQuery.id }); + resetField('query', { defaultValue: savedQuery.query }); + resetField('platform', { + defaultValue: savedQuery.platform ? savedQuery.platform : DEFAULT_PLATFORM, + }); + resetField('version', { defaultValue: savedQuery.version ? [savedQuery.version] : [] }); + resetField('interval', { defaultValue: savedQuery.interval ? savedQuery.interval : 3600 }); + resetField('snapshot', { defaultValue: savedQuery.snapshot ?? true }); + resetField('removed'); + resetField('ecs_mapping', { defaultValue: savedQuery.ecs_mapping ?? {} }); } }, - [clearErrors, setValue] + [resetField] ); /* Avoids accidental closing of the flyout when the user clicks outside of the flyout */ const maskProps = useMemo(() => ({ onClick: () => ({}) }), []); @@ -151,6 +144,8 @@ const QueryFlyoutComponent: React.FC = ({ onCreateOption: undefined, }} /> + +
diff --git a/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx b/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx index 4a1e47c3df9b7..837398a35bf7e 100644 --- a/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx +++ b/x-pack/plugins/osquery/public/packs/queries/use_pack_query_form.tsx @@ -5,15 +5,12 @@ * 2.0. */ -import { isArray, isEmpty, map, xor } from 'lodash'; - +import { isArray, isEmpty, xor } from 'lodash'; import { useForm as useHookForm } from 'react-hook-form'; import type { Draft } from 'immer'; import { produce } from 'immer'; import { useMemo } from 'react'; -import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; -import type { EcsMappingFormField } from './ecs_mapping_editor_field'; -import { defaultEcsFormData } from './ecs_mapping_editor_field'; +import type { ECSMapping } from '../../../common/schemas/common'; export interface UsePackQueryFormProps { uniqueQueryIds: string[]; @@ -24,9 +21,11 @@ export interface PackSOQueryFormData { id: string; query: string; interval: string; + snapshot?: boolean; + removed?: boolean; platform?: string | undefined; version?: string | undefined; - ecs_mapping?: PackQuerySOECSMapping[]; + ecs_mapping?: ECSMapping; } export type PackQuerySOECSMapping = Array<{ field: string; value: string }>; @@ -36,30 +35,23 @@ export interface PackQueryFormData { description?: string; query: string; interval: number; + snapshot?: boolean; + removed?: boolean; platform?: string | undefined; version?: string[] | undefined; - ecs_mapping: EcsMappingFormField[]; + ecs_mapping: ECSMapping; } -const deserializer = (payload: PackSOQueryFormData): PackQueryFormData => - ({ - id: payload.id, - query: payload.query, - interval: payload.interval ? parseInt(payload.interval, 10) : 3600, - platform: payload.platform, - version: payload.version ? [payload.version] : [], - ecs_mapping: !isEmpty(payload.ecs_mapping) - ? !isArray(payload.ecs_mapping) - ? map(payload.ecs_mapping as unknown as PackQuerySOECSMapping, (value, key) => ({ - key, - result: { - type: Object.keys(value)[0], - value: Object.values(value)[0], - }, - })) - : payload.ecs_mapping - : [defaultEcsFormData], - } as PackQueryFormData); +const deserializer = (payload: PackSOQueryFormData): PackQueryFormData => ({ + id: payload.id, + query: payload.query, + interval: payload.interval ? parseInt(payload.interval, 10) : 3600, + snapshot: payload.snapshot, + removed: payload.removed, + platform: payload.platform, + version: payload.version ? [payload.version] : [], + ecs_mapping: payload.ecs_mapping ?? {}, +}); const serializer = (payload: PackQueryFormData): PackSOQueryFormData => // @ts-expect-error update types @@ -86,9 +78,6 @@ const serializer = (payload: PackQueryFormData): PackSOQueryFormData => if (isEmpty(draft.ecs_mapping)) { delete draft.ecs_mapping; - } else { - // @ts-expect-error update types - draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); } return draft; @@ -110,7 +99,8 @@ export const usePackQueryForm = ({ uniqueQueryIds, defaultValue }: UsePackQueryF id: '', query: '', interval: 3600, - ecs_mapping: [defaultEcsFormData], + snapshot: true, + removed: false, }, }), }; diff --git a/x-pack/plugins/osquery/public/packs/types.ts b/x-pack/plugins/osquery/public/packs/types.ts index dcdb03045ab22..941d4f400042d 100644 --- a/x-pack/plugins/osquery/public/packs/types.ts +++ b/x-pack/plugins/osquery/public/packs/types.ts @@ -10,7 +10,7 @@ import type { PackQueryFormData } from './queries/use_pack_query_form'; export type PackSavedObject = SavedObject<{ name: string; description: string | undefined; - queries: PackQueryFormData[]; + queries: Record>; version?: number; enabled: boolean | undefined; created_at: string; diff --git a/x-pack/plugins/osquery/public/packs/use_create_pack.ts b/x-pack/plugins/osquery/public/packs/use_create_pack.ts index 26cf1fad2eeb9..578e80c7234a2 100644 --- a/x-pack/plugins/osquery/public/packs/use_create_pack.ts +++ b/x-pack/plugins/osquery/public/packs/use_create_pack.ts @@ -13,7 +13,7 @@ import { PLUGIN_ID } from '../../common'; import { pagePathGetters } from '../common/page_paths'; import { PACKS_ID } from './constants'; import { useErrorToast } from '../common/hooks/use_error_toast'; -import type { PackSavedObject } from './types'; +import type { PackItem, PackSavedObject } from './types'; interface UseCreatePackProps { withRedirect?: boolean; @@ -31,7 +31,7 @@ export const useCreatePack = ({ withRedirect }: UseCreatePackProps) => { return useMutation< { data: PackSavedObject }, { body: { error: string; message: string } }, - PackSavedObject + Omit >( (payload) => http.post('/api/osquery/packs', { diff --git a/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx b/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx index 86426d432701c..e6f792b5c5423 100644 --- a/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx +++ b/x-pack/plugins/osquery/public/routes/saved_queries/list/index.tsx @@ -20,6 +20,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { useHistory } from 'react-router-dom'; +import deepEqual from 'fast-deep-equal'; import type { SavedObject } from '@kbn/core/public'; import { Direction } from '../../../../common/search_strategy'; @@ -76,7 +77,7 @@ const PlayButtonComponent: React.FC = ({ disabled = false, save ); }; -const PlayButton = React.memo(PlayButtonComponent); +const PlayButton = React.memo(PlayButtonComponent, deepEqual); interface EditButtonProps { disabled?: boolean; diff --git a/x-pack/plugins/osquery/public/saved_queries/form/index.tsx b/x-pack/plugins/osquery/public/saved_queries/form/index.tsx index 6bddd7f0508e4..8ea39cc8d5208 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/index.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/index.tsx @@ -17,7 +17,13 @@ import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { IntervalField, QueryIdField, QueryDescriptionField, VersionField } from '../../form'; +import { + IntervalField, + QueryIdField, + QueryDescriptionField, + VersionField, + ResultsTypeField, +} from '../../form'; import { PlatformCheckBoxGroupField } from '../../packs/queries/platform_checkbox_group_field'; import { ALL_OSQUERY_VERSIONS_OPTIONS } from '../../packs/queries/constants'; import { ECSMappingEditorField } from '../../packs/queries/lazy_ecs_mapping_editor_field'; @@ -92,7 +98,10 @@ const SavedQueryFormComponent: React.FC = ({ - Test configuration + @@ -122,6 +131,8 @@ const SavedQueryFormComponent: React.FC = ({ + + diff --git a/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx b/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx index f8a99cf0e97a4..d2b1f41525327 100644 --- a/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/form/use_saved_query_form.tsx @@ -11,10 +11,6 @@ import type { Draft } from 'immer'; import produce from 'immer'; import { useMemo } from 'react'; import type { ECSMapping } from '../../../common/schemas/common'; -import { convertECSMappingToObject } from '../../../common/schemas/common/utils'; -import type { EcsMappingFormField } from '../../packs/queries/ecs_mapping_editor_field'; -import { defaultEcsFormData } from '../../packs/queries/ecs_mapping_editor_field'; - import { useSavedQueries } from '../use_saved_queries'; export interface SavedQuerySOFormData { @@ -22,6 +18,8 @@ export interface SavedQuerySOFormData { description?: string; query?: string; interval?: string; + snapshot?: boolean; + removed?: boolean; platform?: string; version?: string | undefined; ecs_mapping?: ECSMapping | undefined; @@ -32,9 +30,11 @@ export interface SavedQueryFormData { description?: string; query?: string; interval?: number; + snapshot?: boolean; + removed?: boolean; platform?: string; version?: string[]; - ecs_mapping: EcsMappingFormField[]; + ecs_mapping: ECSMapping | undefined; } interface UseSavedQueryFormProps { @@ -46,17 +46,11 @@ const deserializer = (payload: SavedQuerySOFormData): SavedQueryFormData => ({ description: payload.description, query: payload.query, interval: payload.interval ? parseInt(payload.interval, 10) : 3600, + snapshot: payload.snapshot, + removed: payload.removed, platform: payload.platform, version: payload.version ? [payload.version] : [], - ecs_mapping: !isEmpty(payload.ecs_mapping) - ? (map(payload.ecs_mapping, (value, key: string) => ({ - key, - result: { - type: Object.keys(value)[0], - value: Object.values(value)[0], - }, - })) as unknown as EcsMappingFormField[]) - : [defaultEcsFormData], + ecs_mapping: !isEmpty(payload.ecs_mapping) ? payload.ecs_mapping : {}, }); export const savedQueryDataSerializer = (payload: SavedQueryFormData): SavedQuerySOFormData => @@ -74,12 +68,15 @@ export const savedQueryDataSerializer = (payload: SavedQueryFormData): SavedQuer delete draft.platform; } - draft.ecs_mapping = convertECSMappingToObject(payload.ecs_mapping); - if (draft.interval) { draft.interval = draft.interval + ''; } + if (draft.snapshot) { + delete draft.snapshot; + delete draft.removed; + } + return draft; }); @@ -103,7 +100,7 @@ export const useSavedQueryForm = ({ defaultValue }: UseSavedQueryFormProps) => { id: '', query: '', interval: 3600, - ecs_mapping: [defaultEcsFormData], + ecs_mapping: {}, }, }), }; diff --git a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx index abf8138ff11fa..130f4591ef18f 100644 --- a/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx +++ b/x-pack/plugins/osquery/public/saved_queries/saved_query_flyout.tsx @@ -54,8 +54,6 @@ const SavedQueryFlyoutComponent: React.FC = ({ const onSubmit = useCallback( async (payload: SavedQueryFormData) => { const serializedData = serializer(payload); - // TODO CHECK THIS - // @ts-expect-error update types await createSavedQueryMutation.mutateAsync(serializedData).then(() => onClose()); }, [createSavedQueryMutation, onClose, serializer] diff --git a/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts b/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts index 0d96e4a118736..e4d4619beeee0 100644 --- a/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts +++ b/x-pack/plugins/osquery/public/saved_queries/use_create_saved_query.ts @@ -14,6 +14,7 @@ import { pagePathGetters } from '../common/page_paths'; import { SAVED_QUERIES_ID } from './constants'; import { useErrorToast } from '../common/hooks/use_error_toast'; import type { SavedQuerySO } from '../routes/saved_queries/list'; +import type { SavedQuerySOFormData } from './form/use_saved_query_form'; interface UseCreateSavedQueryProps { withRedirect?: boolean; @@ -28,7 +29,11 @@ export const useCreateSavedQuery = ({ withRedirect }: UseCreateSavedQueryProps) } = useKibana().services; const setErrorToast = useErrorToast(); - return useMutation<{ data: SavedQuerySO }, { body: { error: string; message: string } }>( + return useMutation< + { data: SavedQuerySO }, + { body: { error: string; message: string } }, + SavedQuerySOFormData + >( (payload) => http.post('/api/osquery/saved_queries', { body: JSON.stringify(payload), diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/index.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/index.tsx index 76664f20b9b98..89e92d167d01d 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/index.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/index.tsx @@ -6,21 +6,14 @@ */ import React, { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'; - import { EuiSpacer } from '@elastic/eui'; - import uuid from 'uuid'; import { useForm as useHookForm, FormProvider } from 'react-hook-form'; import { get, isEmpty, map } from 'lodash'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { - convertECSMappingToFormValue, - convertECSMappingToObject, -} from '../../../common/schemas/common/utils'; +import type { ECSMapping } from '../../../common/schemas/common/utils'; import { QueryPackSelectable } from '../../live_queries/form/query_pack_selectable'; -import type { EcsMappingFormField } from '../../packs/queries/ecs_mapping_editor_field'; -import { defaultEcsFormData } from '../../packs/queries/ecs_mapping_editor_field'; import { useFormContext } from '../../shared_imports'; import type { ArrayItem } from '../../shared_imports'; import { useKibana } from '../../common/lib/kibana'; @@ -43,28 +36,28 @@ interface ResponseActionValidatorRef { interface OsqueryResponseActionsParamsFormFields { savedQueryId: string | null; id: string; - ecs_mapping: EcsMappingFormField[]; + ecs_mapping: ECSMapping; query: string; packId?: string[]; queries?: Array<{ id: string; - ecs_mapping: EcsMappingFormField[]; + ecs_mapping: ECSMapping; query: string; }>; } -const OsqueryResponseActionParamsFormComponent: React.ForwardRefExoticComponent< - React.PropsWithoutRef & - React.RefAttributes -> = forwardRef(({ item }, ref) => { +const OsqueryResponseActionParamsFormComponent = forwardRef< + ResponseActionValidatorRef, + OsqueryResponseActionsParamsFormProps +>(({ item }, ref) => { const uniqueId = useMemo(() => uuid.v4(), []); const hooksForm = useHookForm({ defaultValues: { - ecs_mapping: [defaultEcsFormData], + ecs_mapping: {}, id: uniqueId, }, }); - // + const { watch, setValue, register, clearErrors, formState, handleSubmit } = hooksForm; const { errors, isValid } = formState; const context = useFormContext(); @@ -105,7 +98,7 @@ const OsqueryResponseActionParamsFormComponent: React.ForwardRefExoticComponent< id: watchedValues.id, savedQueryId: watchedValues.savedQueryId, query: watchedValues.query, - ecs_mapping: convertECSMappingToObject(watchedValues.ecs_mapping), + ecs_mapping: watchedValues.ecs_mapping, }, }, }); @@ -146,16 +139,12 @@ const OsqueryResponseActionParamsFormComponent: React.ForwardRefExoticComponent< useEffectOnce(() => { if (defaultParams && defaultParams.id) { - const { packId, ecs_mapping: ecsMapping, ...restParams } = defaultParams; + const { packId, ...restParams } = defaultParams; map(restParams, (value, key: keyof OsqueryResponseActionsParamsFormFields) => { if (!isEmpty(value)) { setValue(key, value); } }); - if (ecsMapping) { - const converted = convertECSMappingToFormValue(ecsMapping); - setValue('ecs_mapping', converted); - } if (!isEmpty(packId)) { setValue('packId', [packId]); @@ -167,7 +156,7 @@ const OsqueryResponseActionParamsFormComponent: React.ForwardRefExoticComponent< setValue('packId', []); setValue('savedQueryId', ''); setValue('query', ''); - setValue('ecs_mapping', [defaultEcsFormData]); + setValue('ecs_mapping', {}); clearErrors(); }, [clearErrors, setValue]); diff --git a/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/pack_field_wrapper.tsx b/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/pack_field_wrapper.tsx index a70a046ec4219..54df22217bb16 100644 --- a/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/pack_field_wrapper.tsx +++ b/x-pack/plugins/osquery/public/shared_components/osquery_response_action_type/pack_field_wrapper.tsx @@ -10,7 +10,7 @@ import type { ReactElement } from 'react'; import React, { useMemo } from 'react'; import { find } from 'lodash'; import { useWatch } from 'react-hook-form'; -import type { EcsMappingFormField } from '../../packs/queries/ecs_mapping_editor_field'; +import type { ECSMapping } from '../../../common/schemas/common'; import { PackQueriesStatusTable } from '../../live_queries/form/pack_queries_status_table'; import { usePacks } from '../../packs/use_packs'; import { PacksComboBoxField } from '../../live_queries/form/packs_combobox_field'; @@ -20,7 +20,7 @@ interface PackFieldWrapperProps { queries?: Array<{ id: string; query: string; - ecs_mapping?: EcsMappingFormField[]; + ecs_mapping?: ECSMapping; }>; action_id?: string; agents?: string[]; @@ -39,7 +39,7 @@ export const PackFieldWrapper = ({ showResultsHeader, }: PackFieldWrapperProps) => { const { data: packsData } = usePacks({}); - const { packId } = useWatch() as unknown as { packId: string[] }; + const { packId } = useWatch<{ packId: string[] }>(); const selectedPackData = useMemo( () => (packId?.length ? find(packsData?.data, { id: packId[0] }) : null), @@ -55,7 +55,7 @@ export const PackFieldWrapper = ({ {submitButtonContent} @@ -67,6 +67,7 @@ export const PackFieldWrapper = ({ ; }>; version?: number; @@ -40,6 +42,8 @@ export interface SavedQuerySavedObjectAttributes { description: string | undefined; query: string; interval: number | string; + snapshot?: boolean; + removed?: boolean; platform: string; ecs_mapping?: Array>; created_at: string; diff --git a/x-pack/plugins/osquery/server/lib/saved_query/saved_object_mappings.ts b/x-pack/plugins/osquery/server/lib/saved_query/saved_object_mappings.ts index dccbd77f0505f..c915b15e603f5 100644 --- a/x-pack/plugins/osquery/server/lib/saved_query/saved_object_mappings.ts +++ b/x-pack/plugins/osquery/server/lib/saved_query/saved_object_mappings.ts @@ -33,6 +33,7 @@ export const usageMetricType: SavedObjectsType = { }; export const savedQuerySavedObjectMappings: SavedObjectsType['mappings'] = { + dynamic: false, properties: { description: { type: 'text', @@ -126,6 +127,7 @@ export const packSavedObjectMappings: SavedObjectsType['mappings'] = { type: 'long', }, queries: { + dynamic: false, properties: { id: { type: 'keyword', @@ -194,6 +196,7 @@ export const packAssetSavedObjectMappings: SavedObjectsType['mappings'] = { type: 'long', }, queries: { + dynamic: false, properties: { id: { type: 'keyword', diff --git a/x-pack/plugins/osquery/server/lib/telemetry/filters.ts b/x-pack/plugins/osquery/server/lib/telemetry/filters.ts index 513242ffb583d..fd2c6536a126e 100644 --- a/x-pack/plugins/osquery/server/lib/telemetry/filters.ts +++ b/x-pack/plugins/osquery/server/lib/telemetry/filters.ts @@ -19,6 +19,8 @@ export const savedQueryEventFields: AllowlistFields = { platform: true, version: true, interval: true, + snapshot: true, + removed: true, ecs_mapping: true, }; diff --git a/x-pack/plugins/osquery/server/lib/telemetry/helpers.ts b/x-pack/plugins/osquery/server/lib/telemetry/helpers.ts index b9ceb105c39ed..0754ebc74bd5f 100644 --- a/x-pack/plugins/osquery/server/lib/telemetry/helpers.ts +++ b/x-pack/plugins/osquery/server/lib/telemetry/helpers.ts @@ -63,6 +63,8 @@ export const templateSavedQueries = ( interval: isString(item.attributes.interval) ? parseInt(item.attributes.interval, 10) : item.attributes.interval, + ...(!isEmpty(item.attributes.snapshot) ? { snapshot: item.attributes.snapshot } : {}), + ...(!isEmpty(item.attributes.removed) ? { snapshot: item.attributes.removed } : {}), ...(!isEmpty(item.attributes.ecs_mapping) ? { ecs_mapping: item.attributes.ecs_mapping } : {}), prebuilt: prebuiltSavedQueryIds.includes(item.id), })); diff --git a/x-pack/plugins/osquery/server/lib/telemetry/sender.ts b/x-pack/plugins/osquery/server/lib/telemetry/sender.ts index d9bce6f9166e4..512cf874a1781 100644 --- a/x-pack/plugins/osquery/server/lib/telemetry/sender.ts +++ b/x-pack/plugins/osquery/server/lib/telemetry/sender.ts @@ -199,6 +199,18 @@ export class TelemetryEventsSender { optional: true, }, }, + snapshot: { + type: 'boolean', + _meta: { + description: '', + }, + }, + removed: { + type: 'boolean', + _meta: { + description: '', + }, + }, prebuilt: { type: 'boolean', _meta: { diff --git a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts index 5f5cd40e815d8..c60c6d476974b 100644 --- a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts @@ -39,6 +39,8 @@ export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppConte schema.object({ query: schema.string(), interval: schema.maybe(schema.number()), + snapshot: schema.maybe(schema.boolean()), + removed: schema.maybe(schema.boolean()), platform: schema.maybe(schema.string()), version: schema.maybe(schema.string()), ecs_mapping: schema.maybe( diff --git a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts index 0afdbe6dd005a..c113cbeb36c32 100644 --- a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts @@ -47,6 +47,8 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte schema.object({ query: schema.string(), interval: schema.maybe(schema.number()), + snapshot: schema.maybe(schema.boolean()), + removed: schema.maybe(schema.boolean()), platform: schema.maybe(schema.string()), version: schema.maybe(schema.string()), ecs_mapping: schema.maybe( diff --git a/x-pack/plugins/osquery/server/routes/pack/utils.test.ts b/x-pack/plugins/osquery/server/routes/pack/utils.test.ts index 97905fde6bf02..05aff28073937 100644 --- a/x-pack/plugins/osquery/server/routes/pack/utils.test.ts +++ b/x-pack/plugins/osquery/server/routes/pack/utils.test.ts @@ -33,7 +33,6 @@ const getTestQueries = (additionalFields?: Record, packName = ' const oneLiner = { default: { - ecs_mapping: {}, interval: 3600, query: `select u.username, p.pid, p.name, pos.local_address, pos.local_port, p.path, p.cmdline, pos.remote_address, pos.remote_port from processes as p join users as u on u.uid=p.uid join process_open_sockets as pos on pos.pid=p.pid where pos.remote_port !='0' limit 1000;`, }, @@ -43,7 +42,7 @@ describe('Pack utils', () => { describe('convertSOQueriesToPack', () => { test('converts to pack with empty ecs_mapping', () => { const convertedQueries = convertSOQueriesToPack(getTestQueries()); - expect(convertedQueries).toStrictEqual(getTestQueries({ ecs_mapping: {} })); + expect(convertedQueries).toStrictEqual(getTestQueries({})); }); test('converts to pack with converting query to single line', () => { const convertedQueries = convertSOQueriesToPack(getTestQueries(), { removeMultiLines: true }); @@ -51,7 +50,7 @@ describe('Pack utils', () => { }); test('converts to object with pack names after query.id', () => { const convertedQueries = convertSOQueriesToPack(getTestQueries({ id: 'testId' })); - expect(convertedQueries).toStrictEqual(getTestQueries({ ecs_mapping: {} }, 'testId')); + expect(convertedQueries).toStrictEqual(getTestQueries({}, 'testId')); }); }); }); diff --git a/x-pack/plugins/osquery/server/routes/pack/utils.ts b/x-pack/plugins/osquery/server/routes/pack/utils.ts index b4c1bdfa85373..fe1ded84f4466 100644 --- a/x-pack/plugins/osquery/server/routes/pack/utils.ts +++ b/x-pack/plugins/osquery/server/routes/pack/utils.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { pick, reduce } from 'lodash'; +import { isEmpty, pick, reduce } from 'lodash'; +import { DEFAULT_PLATFORM } from '../../../common/constants'; import { removeMultilines } from '../../../common/utils/build_query/remove_multilines'; import { convertECSMappingToArray, convertECSMappingToObject } from '../utils'; @@ -18,6 +19,8 @@ export const convertPackQueriesToSO = (queries) => acc.push({ id: key, ...pick(value, ['name', 'query', 'interval', 'platform', 'version']), + ...(value.snapshot !== undefined ? { snapshot: value.snapshot } : {}), + ...(value.removed !== undefined ? { removed: value.removed } : {}), ...(ecsMapping ? { ecs_mapping: ecsMapping } : {}), }); @@ -28,6 +31,8 @@ export const convertPackQueriesToSO = (queries) => name: string; query: string; interval: number; + snapshot?: boolean; + removed?: boolean; ecs_mapping?: Record; }> ); @@ -37,12 +42,13 @@ export const convertSOQueriesToPack = (queries, options?: { removeMultiLines?: b reduce( queries, // eslint-disable-next-line @typescript-eslint/naming-convention - (acc, { id: queryId, ecs_mapping, query, ...rest }, key) => { + (acc, { id: queryId, ecs_mapping, query, platform, ...rest }, key) => { const index = queryId ? queryId : key; acc[index] = { ...rest, query: options?.removeMultiLines ? removeMultilines(query) : query, - ecs_mapping: convertECSMappingToObject(ecs_mapping), + ...(!isEmpty(ecs_mapping) ? { ecs_mapping: convertECSMappingToObject(ecs_mapping) } : {}), + ...(platform === DEFAULT_PLATFORM || platform === undefined ? {} : { platform }), }; return acc; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts index 8ee9cef33477f..206719927281b 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts @@ -31,8 +31,18 @@ export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp const coreContext = await context.core; const savedObjectsClient = coreContext.savedObjects.client; - // eslint-disable-next-line @typescript-eslint/naming-convention - const { id, description, platform, query, version, interval, ecs_mapping } = request.body; + const { + id, + description, + platform, + query, + version, + interval, + snapshot, + removed, + // eslint-disable-next-line @typescript-eslint/naming-convention + ecs_mapping, + } = request.body; const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; @@ -58,13 +68,15 @@ export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp platform, version, interval, + snapshot, + removed, ecs_mapping: convertECSMappingToArray(ecs_mapping), created_by: currentUser, created_at: new Date().toISOString(), updated_by: currentUser, updated_at: new Date().toISOString(), }, - (value) => !isEmpty(value) + (value) => !isEmpty(value) || value === false ) ); diff --git a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts index df1647ebc8d37..b83787794c2b7 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts @@ -29,6 +29,8 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp query: schema.string(), description: schema.maybe(schema.string()), interval: schema.maybe(schema.number()), + snapshot: schema.maybe(schema.boolean()), + removed: schema.maybe(schema.boolean()), platform: schema.maybe(schema.string()), version: schema.maybe(schema.string()), ecs_mapping: schema.maybe( @@ -60,6 +62,8 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp query, version, interval, + snapshot, + removed, // eslint-disable-next-line @typescript-eslint/naming-convention ecs_mapping, } = request.body; @@ -97,6 +101,8 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp query, version, interval, + snapshot, + removed, ecs_mapping: convertECSMappingToArray(ecs_mapping), updated_by: currentUser, updated_at: new Date().toISOString(), From 3be835a9425e28a7044c0b0299a599f9d029e41a Mon Sep 17 00:00:00 2001 From: Rickyanto Ang Date: Tue, 20 Sep 2022 16:36:19 -0700 Subject: [PATCH 24/55] [8.5][Elastic Defend onboarding] Endpoint and Cloud settings (#139230) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Paulo Henrique --- .../endpoint_policy_create_extension.tsx | 50 --- .../endpoint_policy_create_extension.tsx | 370 ++++++++++++++++++ .../index.tsx | 8 + .../translations.ts | 65 +++ .../handlers/create_default_policy.ts | 4 +- .../handlers/validate_integration_config.ts | 8 +- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 9 files changed, 446 insertions(+), 62 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/index.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension.tsx deleted file mode 100644 index e83482e560cb0..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension.tsx +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useEffect } from 'react'; -import { EuiCallOut, EuiSpacer, EuiText } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { PackagePolicyCreateExtensionComponentProps } from '@kbn/fleet-plugin/public'; - -/** - * Exports Endpoint-specific package policy instructions - * for use in the Ingest app create / edit package policy - */ -export const EndpointPolicyCreateExtension = memo( - ({ newPolicy, onChange }) => { - // Fleet will initialize the create form with a default name for the integratin policy, however, - // for endpoint security, we want the user to explicitely type in a name, so we blank it out - // only during 1st component render (thus why the eslint disabled rule below). - useEffect(() => { - onChange({ - isValid: false, - updatedPolicy: { - ...newPolicy, - name: '', - }, - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return ( - <> - - - -

- -

-
-
- - ); - } -); -EndpointPolicyCreateExtension.displayName = 'EndpointPolicyCreateExtension'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx new file mode 100644 index 0000000000000..9a4dc273740e5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx @@ -0,0 +1,370 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useState, useEffect, useRef, useCallback } from 'react'; +import { + EuiForm, + EuiCheckbox, + EuiRadio, + EuiSelect, + EuiText, + EuiTitle, + EuiSpacer, + EuiFormRow, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import styled from 'styled-components'; +import type { PackagePolicyCreateExtensionComponentProps } from '@kbn/fleet-plugin/public'; +import { useLicense } from '../../../../../../common/hooks/use_license'; +import { + ALL_EVENTS, + CLOUD_SECURITY, + EDR_COMPLETE, + NGAV, + EDR_ESSENTIAL, + ENDPOINT, + INTERACTIVE_ONLY, + PREVENT_MALICIOUS_BEHAVIOUR, +} from './translations'; + +const PREFIX = 'endpoint_policy_create_extension'; + +const ENDPOINT_INTEGRATION_CONFIG_KEY = 'ENDPOINT_INTEGRATION_CONFIG'; + +const environmentMapping = { + cloud: CLOUD_SECURITY, + endpoint: ENDPOINT, +}; + +const endpointPresetsMapping = { + NGAV, + EDREssential: EDR_ESSENTIAL, + EDRComplete: EDR_COMPLETE, +}; + +const cloudEventMapping = { + INTERACTIVE_ONLY, + ALL_EVENTS, +}; + +type EndpointPreset = keyof typeof endpointPresetsMapping; +type CloudEvent = keyof typeof cloudEventMapping; +type Environment = keyof typeof environmentMapping; + +const environmentOptions: Array<{ value: Environment; text: string }> = [ + { value: 'endpoint', text: ENDPOINT }, + { value: 'cloud', text: CLOUD_SECURITY }, +]; + +const HelpTextWithPadding = styled.div` + padding-left: ${(props) => props.theme.eui.euiSizeL}; +`; + +/** + * Exports Endpoint-specific package policy instructions + * for use in the Ingest app create / edit package policy + */ +export const EndpointPolicyCreateExtension = memo( + ({ newPolicy, onChange }) => { + const isPlatinumPlus = useLicense().isPlatinumPlus(); + + // / Endpoint Radio Options (NGAV and EDRs) + const [endpointPreset, setEndpointPreset] = useState('NGAV'); + const [behaviorProtectionChecked, setBehaviorProtectionChecked] = useState(false); + const [selectedCloudEvent, setSelectedCloudEvent] = useState('INTERACTIVE_ONLY'); + const [selectedEnvironment, setSelectedEnvironment] = useState('endpoint'); + const initialRender = useRef(true); + + // Fleet will initialize the create form with a default name for the integratin policy, however, + // for endpoint security, we want the user to explicitely type in a name, so we blank it out + // only during 1st component render (thus why the eslint disabled rule below). + // Default values for config are endpoint + NGAV + useEffect(() => { + if (initialRender.current) { + onChange({ + isValid: false, + updatedPolicy: { + ...newPolicy, + name: '', + inputs: [ + { + enabled: true, + streams: [], + type: ENDPOINT_INTEGRATION_CONFIG_KEY, + config: { + _config: { + value: { + type: 'endpoint', + endpointConfig: { + preset: 'NGAV', + }, + }, + }, + }, + }, + ], + }, + }); + } + }, [onChange, newPolicy]); + + useEffect(() => { + // Skip trigerring this onChange on the initial render + if (initialRender.current) { + initialRender.current = false; + } else { + onChange({ + isValid: true, + updatedPolicy: { + ...newPolicy, + inputs: [ + { + ...newPolicy.inputs[0], + config: { + _config: { + value: { + type: selectedEnvironment, + ...(selectedEnvironment === 'cloud' + ? { + cloudConfig: { + preventions: { + behavior_protection: behaviorProtectionChecked, + }, + }, + eventFilters: { + nonInteractiveSession: selectedCloudEvent === 'INTERACTIVE_ONLY', + }, + } + : { + endpointConfig: { + preset: endpointPreset, + }, + }), + }, + }, + }, + }, + ], + }, + }); + } + }, [ + selectedEnvironment, + behaviorProtectionChecked, + selectedCloudEvent, + endpointPreset, + onChange, + newPolicy, + ]); + + const onChangeEnvironment = useCallback((e: React.ChangeEvent) => { + setSelectedEnvironment(e?.target?.value as Environment); + }, []); + const onChangeCloudEvent = useCallback((e: React.ChangeEvent) => { + setSelectedCloudEvent(e.target.value as CloudEvent); + }, []); + const onChangeEndpointPreset = useCallback((e: React.ChangeEvent) => { + setEndpointPreset(e.target.value as EndpointPreset); + }, []); + const onChangeMaliciousBehavior = useCallback((e: React.ChangeEvent) => { + setBehaviorProtectionChecked((checked) => !checked); + }, []); + + const getEndpointPresetsProps = useCallback( + (preset: EndpointPreset) => ({ + id: `${PREFIX}_endpoint_preset_${preset}`, + label: endpointPresetsMapping[preset], + value: preset, + checked: endpointPreset === preset, + onChange: onChangeEndpointPreset, + }), + [endpointPreset, onChangeEndpointPreset] + ); + + const getCloudEventsProps = useCallback( + (cloudEvent: CloudEvent) => ({ + id: `${PREFIX}_cloud_event_${cloudEvent}`, + label: cloudEventMapping[cloudEvent], + value: cloudEvent, + checked: selectedCloudEvent === cloudEvent, + onChange: onChangeCloudEvent, + }), + [selectedCloudEvent, onChangeCloudEvent] + ); + + return ( + + +

+ +

+
+ + +

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

+
+ + + } + > + + + {selectedEnvironment === 'endpoint' ? ( + <> + + + + + } + > + + + + + + + } + > + + + + + + + } + > + + + + ) : ( + <> + + +

+ +

+
+ + + + + } + > + + + + + + + } + > + + + {isPlatinumPlus && ( + <> + + +

+ +

+
+ + +

+ +

+
+ + + + )} + + )} + +
+ ); + }, + (prevProps, nextProps) => { + return prevProps.newPolicy.name === nextProps.newPolicy.name; + } +); +EndpointPolicyCreateExtension.displayName = 'EndpointPolicyCreateExtension'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/index.tsx new file mode 100644 index 0000000000000..9be04def1c64e --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/index.tsx @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { EndpointPolicyCreateExtension } from './endpoint_policy_create_extension'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts new file mode 100644 index 0000000000000..b50835b36995b --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const NGAV = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.endpointDropdownOptionNGAV', + { + defaultMessage: 'NGAV', + } +); + +export const EDR_ESSENTIAL = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.endpointDropdownOptionEDREssential', + { + defaultMessage: 'EDR Essential', + } +); +export const EDR_COMPLETE = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.endpointDropdownOptionEDRComplete', + { + defaultMessage: 'EDR Complete', + } +); + +export const ENDPOINT = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.endpointDropdownOption', + { + defaultMessage: 'Endpoint', + } +); +export const CLOUD_SECURITY = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudSecurityDropdownOption', + { + defaultMessage: 'Cloud Security', + } +); +export const INTERACTIVE_ONLY = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudEventFiltersInteractiveOnly', + { + defaultMessage: 'Interactive only', + } +); +export const ALL_EVENTS = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudEventFiltersAllEvents', + { + defaultMessage: 'All events', + } +); +export const PREVENT_MALWARE = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudEventFiltersPreventionMalware', + { + defaultMessage: 'Prevent Malware', + } +); +export const PREVENT_MALICIOUS_BEHAVIOUR = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudEventFiltersPreventionMaliciousBehaviour', + { + defaultMessage: 'Prevent Malicious Behaviour', + } +); diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.ts index 47b4840665e64..8ffd33e070d98 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.ts @@ -120,8 +120,8 @@ const getCloudPolicyWithIntegrationConfig = ( }, malware: { ...policy.linux.malware, - // Malware protection mode based on cloud settings - mode: config.cloudConfig.preventions.malware ? ProtectionModes.prevent : ProtectionModes.off, + // Disabling Malware protection, since it's not supported on Cloud integrations due to performance reasons + mode: ProtectionModes.off, }, behavior_protection: { ...policy.linux.behavior_protection, diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_integration_config.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_integration_config.ts index d56dd6a02d4cd..76bd3e8af93fb 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_integration_config.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/validate_integration_config.ts @@ -48,7 +48,7 @@ const validateEndpointIntegrationConfig = ( const validateCloudIntegrationConfig = (config: PolicyCreateCloudConfig, logger: Logger): void => { if (!config?.cloudConfig?.preventions) { logger.warn( - 'missing cloudConfig preventions: {preventions : malware: true / false, behavior_protection: true / false}' + 'missing cloudConfig preventions: {preventions : behavior_protection: true / false}' ); throwError('invalid value for cloudConfig: missing preventions '); } @@ -58,12 +58,6 @@ const validateCloudIntegrationConfig = (config: PolicyCreateCloudConfig, logger: ); throwError('invalid value for cloudConfig preventions behavior_protection'); } - if (typeof config.cloudConfig.preventions.malware !== 'boolean') { - logger.warn( - `invalid value for cloudConfig preventions malware: ${config.cloudConfig.preventions.malware}` - ); - throwError('invalid value for cloudConfig preventions malware'); - } if (!config?.eventFilters) { logger.warn( `eventFilters is required for cloud integration: {eventFilters : nonInteractiveSession: true / false}` diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 8b5324cdd51fc..270aba534f81b 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -27387,7 +27387,6 @@ "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingRunningProcesses": "Processus", "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingSuspendProcess": "Suspendre le processus", "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingUnIsolate": "Libération", - "xpack.securitySolution.endpoint.ingestManager.createPackagePolicy.endpointConfiguration": "Nous enregistrerons votre intégration avec nos valeurs par défaut recommandées. Vous pourrez les changer ultérieurement en modifiant l'intégration Endpoint and Cloud Security dans la politique de votre agent.", "xpack.securitySolution.endpoint.list.actionmenu": "Ouvrir", "xpack.securitySolution.endpoint.list.actions": "Actions", "xpack.securitySolution.endpoint.list.backToPolicyButton": "Retour à la liste des politiques", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 106718f0c2ade..b24713361e882 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -27362,7 +27362,6 @@ "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingRunningProcesses": "プロセス", "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingSuspendProcess": "プロセスを一時停止", "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingUnIsolate": "リリース", - "xpack.securitySolution.endpoint.ingestManager.createPackagePolicy.endpointConfiguration": "推奨のデフォルト値で統合が保存されます。後からこれを変更するには、エージェントポリシー内でエンドポイントおよびクラウドセキュリティ統合を編集します。", "xpack.securitySolution.endpoint.list.actionmenu": "開く", "xpack.securitySolution.endpoint.list.actions": "アクション", "xpack.securitySolution.endpoint.list.backToPolicyButton": "ポリシーリストに戻る", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 553d66f841859..313c4fc3b9185 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -27393,7 +27393,6 @@ "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingRunningProcesses": "进程", "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingSuspendProcess": "挂起进程", "xpack.securitySolution.endpoint.hostIsolationStatus.tooltipPendingUnIsolate": "释放", - "xpack.securitySolution.endpoint.ingestManager.createPackagePolicy.endpointConfiguration": "我们将使用建议的默认值保存您的集成。稍后,您可以通过在代理策略中编辑终端和云安全集成对其进行更改。", "xpack.securitySolution.endpoint.list.actionmenu": "打开", "xpack.securitySolution.endpoint.list.actions": "操作", "xpack.securitySolution.endpoint.list.backToPolicyButton": "返回到策略列表", From 4acc6e5d6a64b060510c8d74441994785f28071b Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Tue, 20 Sep 2022 17:56:12 -0600 Subject: [PATCH 25/55] [ML] Explain Log Rate Spikes: add main chart sync on row hover at group level (#141138) * add hover main chart sync at group level * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * fix overall request with groups * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * ensure all pairs in group are considered in query * add alignment to log rate column * fix types Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../public/application/utils/query_utils.ts | 38 ++++++++++++++++--- .../explain_log_rate_spikes_analysis.tsx | 4 ++ .../explain_log_rate_spikes_page.tsx | 12 +++++- .../spike_analysis_table_groups.tsx | 15 +++++++- .../aiops/public/get_document_stats.ts | 6 ++- x-pack/plugins/aiops/public/hooks/use_data.ts | 24 +++++++++--- 6 files changed, 84 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/aiops/public/application/utils/query_utils.ts b/x-pack/plugins/aiops/public/application/utils/query_utils.ts index 85ad3d236a98e..1779b434df508 100644 --- a/x-pack/plugins/aiops/public/application/utils/query_utils.ts +++ b/x-pack/plugins/aiops/public/application/utils/query_utils.ts @@ -16,6 +16,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { Query } from '@kbn/es-query'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; import type { ChangePoint } from '@kbn/ml-agg-utils'; +import type { GroupTableItem } from '../../components/spike_analysis_table/spike_analysis_table_groups'; /* * Contains utility functions for building and processing queries. @@ -29,7 +30,8 @@ export function buildBaseFilterCriteria( latestMs?: number, query?: Query['query'], selectedChangePoint?: ChangePoint, - includeSelectedChangePoint = true + includeSelectedChangePoint = true, + selectedGroup?: GroupTableItem | null ): estypes.QueryDslQueryContainer[] { const filterCriteria = []; if (timeFieldName && earliestMs && latestMs) { @@ -48,10 +50,24 @@ export function buildBaseFilterCriteria( filterCriteria.push(query); } - if (selectedChangePoint && includeSelectedChangePoint) { - filterCriteria.push({ - term: { [selectedChangePoint.fieldName]: selectedChangePoint.fieldValue }, - }); + const groupFilter = []; + if (selectedGroup) { + const allItems = { ...selectedGroup.group, ...selectedGroup.repeatedValues }; + for (const fieldName in allItems) { + if (allItems.hasOwnProperty(fieldName)) { + groupFilter.push({ term: { [fieldName]: allItems[fieldName] } }); + } + } + } + + if (includeSelectedChangePoint) { + if (selectedChangePoint) { + filterCriteria.push({ + term: { [selectedChangePoint.fieldName]: selectedChangePoint.fieldValue }, + }); + } else if (selectedGroup) { + filterCriteria.push(...groupFilter); + } } else if (selectedChangePoint && !includeSelectedChangePoint) { filterCriteria.push({ bool: { @@ -62,6 +78,18 @@ export function buildBaseFilterCriteria( ], }, }); + } else if (selectedGroup && !includeSelectedChangePoint) { + filterCriteria.push({ + bool: { + must_not: [ + { + bool: { + filter: [...groupFilter], + }, + }, + ], + }, + }); } return filterCriteria; 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 b317ac6f2fed8..a0fb825ee4064 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 @@ -32,6 +32,7 @@ import type { ApiExplainLogRateSpikes } from '../../../common/api'; import { SpikeAnalysisGroupsTable } from '../spike_analysis_table'; import { SpikeAnalysisTable } from '../spike_analysis_table'; +import { GroupTableItem } from '../spike_analysis_table/spike_analysis_table_groups'; const groupResultsMessage = i18n.translate( 'xpack.aiops.spikeAnalysisTable.groupedSwitchLabel.groupResults', @@ -56,6 +57,7 @@ interface ExplainLogRateSpikesAnalysisProps { onPinnedChangePoint?: (changePoint: ChangePoint | null) => void; onSelectedChangePoint?: (changePoint: ChangePoint | null) => void; selectedChangePoint?: ChangePoint; + onSelectedGroup?: (group: GroupTableItem | null) => void; } export const ExplainLogRateSpikesAnalysis: FC = ({ @@ -67,6 +69,7 @@ export const ExplainLogRateSpikesAnalysis: FC onPinnedChangePoint, onSelectedChangePoint, selectedChangePoint, + onSelectedGroup, }) => { const { http } = useAiopsAppContext(); const basePath = http.basePath.get() ?? ''; @@ -249,6 +252,7 @@ export const ExplainLogRateSpikesAnalysis: FC onPinnedChangePoint={onPinnedChangePoint} onSelectedChangePoint={onSelectedChangePoint} selectedChangePoint={selectedChangePoint} + onSelectedGroup={onSelectedGroup} dataViewId={dataView.id} /> ) : null} diff --git a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx index bdc91175c2913..feff4f2e8211f 100644 --- a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx +++ b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx @@ -37,6 +37,7 @@ import { SearchPanel } from '../search_panel'; import { restorableDefaults } from './explain_log_rate_spikes_app_state'; import { ExplainLogRateSpikesAnalysis } from './explain_log_rate_spikes_analysis'; +import type { GroupTableItem } from '../spike_analysis_table/spike_analysis_table_groups'; // TODO port to `@emotion/react` once `useEuiBreakpoint` is available https://github.com/elastic/eui/pull/6057 import './explain_log_rate_spikes_page.scss'; @@ -94,6 +95,7 @@ export const ExplainLogRateSpikesPage: FC = ({ const [pinnedChangePoint, setPinnedChangePoint] = useState(null); const [selectedChangePoint, setSelectedChangePoint] = useState(null); + const [selectedGroup, setSelectedGroup] = useState(null); // If a row is pinned, still overrule with a potentially hovered row. const currentSelectedChangePoint = useMemo(() => { @@ -116,7 +118,9 @@ export const ExplainLogRateSpikesPage: FC = ({ { currentDataView: dataView, currentSavedSearch }, aiopsListState, setGlobalState, - currentSelectedChangePoint + currentSelectedChangePoint, + undefined, + selectedGroup ); const { totalCount, documentCountStats, documentCountStatsCompare } = documentStats; @@ -167,6 +171,7 @@ export const ExplainLogRateSpikesPage: FC = ({ setWindowParameters(undefined); setPinnedChangePoint(null); setSelectedChangePoint(null); + setSelectedGroup(null); } return ( @@ -225,7 +230,9 @@ export const ExplainLogRateSpikesPage: FC = ({ clearSelectionHandler={clearSelection} documentCountStats={documentCountStats} documentCountStatsSplit={ - currentSelectedChangePoint ? documentCountStatsCompare : undefined + currentSelectedChangePoint || selectedGroup + ? documentCountStatsCompare + : undefined } totalCount={totalCount} changePoint={currentSelectedChangePoint} @@ -246,6 +253,7 @@ export const ExplainLogRateSpikesPage: FC = ({ onPinnedChangePoint={setPinnedChangePoint} onSelectedChangePoint={setSelectedChangePoint} selectedChangePoint={currentSelectedChangePoint} + onSelectedGroup={setSelectedGroup} /> )} {windowParameters === undefined && ( diff --git a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx index c8f8410a56448..a7503e7d49111 100644 --- a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx +++ b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx @@ -50,7 +50,7 @@ const viewInDiscoverMessage = i18n.translate( } ); -interface GroupTableItem { +export interface GroupTableItem { id: string; docCount: number; pValue: number | null; @@ -67,6 +67,7 @@ interface SpikeAnalysisTableProps { onPinnedChangePoint?: (changePoint: ChangePoint | null) => void; onSelectedChangePoint?: (changePoint: ChangePoint | null) => void; selectedChangePoint?: ChangePoint; + onSelectedGroup?: (group: GroupTableItem | null) => void; } export const SpikeAnalysisGroupsTable: FC = ({ @@ -77,6 +78,7 @@ export const SpikeAnalysisGroupsTable: FC = ({ onPinnedChangePoint, onSelectedChangePoint, selectedChangePoint, + onSelectedGroup, }) => { const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(10); @@ -316,6 +318,7 @@ export const SpikeAnalysisGroupsTable: FC = ({ /> ), sortable: false, + valign: 'top', }, { 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnDocCount', @@ -470,6 +473,16 @@ export const SpikeAnalysisGroupsTable: FC = ({ rowProps={(group) => { return { 'data-test-subj': `aiopsSpikeAnalysisGroupsTableRow row-${group.id}`, + onMouseEnter: () => { + if (onSelectedGroup) { + onSelectedGroup(group); + } + }, + onMouseLeave: () => { + if (onSelectedGroup) { + onSelectedGroup(null); + } + }, }; }} /> diff --git a/x-pack/plugins/aiops/public/get_document_stats.ts b/x-pack/plugins/aiops/public/get_document_stats.ts index 1df4e4bd57ae8..07324b5f10605 100644 --- a/x-pack/plugins/aiops/public/get_document_stats.ts +++ b/x-pack/plugins/aiops/public/get_document_stats.ts @@ -14,6 +14,7 @@ import type { ChangePoint } from '@kbn/ml-agg-utils'; import type { Query } from '@kbn/es-query'; import { buildBaseFilterCriteria } from './application/utils/query_utils'; +import { GroupTableItem } from './components/spike_analysis_table/spike_analysis_table_groups'; export interface DocumentCountStats { interval?: number; @@ -34,6 +35,7 @@ export interface DocumentStatsSearchStrategyParams { fieldsToFetch?: string[]; selectedChangePoint?: ChangePoint; includeSelectedChangePoint?: boolean; + selectedGroup?: GroupTableItem | null; } export const getDocumentCountStatsRequest = (params: DocumentStatsSearchStrategyParams) => { @@ -48,6 +50,7 @@ export const getDocumentCountStatsRequest = (params: DocumentStatsSearchStrategy fieldsToFetch, selectedChangePoint, includeSelectedChangePoint, + selectedGroup, } = params; const size = 0; @@ -57,7 +60,8 @@ export const getDocumentCountStatsRequest = (params: DocumentStatsSearchStrategy latestMs, searchQuery, selectedChangePoint, - includeSelectedChangePoint + includeSelectedChangePoint, + selectedGroup ); // Don't use the sampler aggregation as this can lead to some potentially diff --git a/x-pack/plugins/aiops/public/hooks/use_data.ts b/x-pack/plugins/aiops/public/hooks/use_data.ts index 9ea8f9bd2335b..05736fe00e4fc 100644 --- a/x-pack/plugins/aiops/public/hooks/use_data.ts +++ b/x-pack/plugins/aiops/public/hooks/use_data.ts @@ -28,6 +28,7 @@ import { import { useTimefilter } from './use_time_filter'; import { useDocumentCountStats } from './use_document_count_stats'; import type { Dictionary } from './use_url_state'; +import type { GroupTableItem } from '../components/spike_analysis_table/spike_analysis_table_groups'; const DEFAULT_BAR_TARGET = 75; @@ -39,7 +40,8 @@ export const useData = ( aiopsListState: AiOpsIndexBasedAppState, onUpdate: (params: Dictionary) => void, selectedChangePoint?: ChangePoint, - barTarget: number = DEFAULT_BAR_TARGET + barTarget: number = DEFAULT_BAR_TARGET, + selectedGroup?: GroupTableItem | null ) => { const { uiSettings, @@ -109,15 +111,25 @@ export const useData = ( const overallStatsRequest = useMemo(() => { return fieldStatsRequest - ? { ...fieldStatsRequest, selectedChangePoint, includeSelectedChangePoint: false } + ? { + ...fieldStatsRequest, + selectedChangePoint, + selectedGroup, + includeSelectedChangePoint: false, + } : undefined; - }, [fieldStatsRequest, selectedChangePoint]); + }, [fieldStatsRequest, selectedChangePoint, selectedGroup]); const selectedChangePointStatsRequest = useMemo(() => { - return fieldStatsRequest && selectedChangePoint - ? { ...fieldStatsRequest, selectedChangePoint, includeSelectedChangePoint: true } + return fieldStatsRequest && (selectedChangePoint || selectedGroup) + ? { + ...fieldStatsRequest, + selectedChangePoint, + selectedGroup, + includeSelectedChangePoint: true, + } : undefined; - }, [fieldStatsRequest, selectedChangePoint]); + }, [fieldStatsRequest, selectedChangePoint, selectedGroup]); const documentStats = useDocumentCountStats( overallStatsRequest, From 9fa1f047252b65b2ea320d557cb6a1036102b162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 20 Sep 2022 20:06:15 -0400 Subject: [PATCH 26/55] [APM] [Labs] Adding bottom bar (#140992) * adding bottom save bar * addressing pr changes --- .../settings_page/settings_page.tsx | 66 +++------------ .../app/settings/bottom_bar_actions/index.tsx | 81 +++++++++++++++++++ .../app/settings/general_settings/index.tsx | 24 +++--- .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 6 files changed, 107 insertions(+), 70 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/app/settings/bottom_bar_actions/index.tsx diff --git a/x-pack/plugins/apm/public/components/app/settings/agent_configurations/agent_configuration_create_edit/settings_page/settings_page.tsx b/x-pack/plugins/apm/public/components/app/settings/agent_configurations/agent_configuration_create_edit/settings_page/settings_page.tsx index f4e8f52cdc1df..94357cf4fb63f 100644 --- a/x-pack/plugins/apm/public/components/app/settings/agent_configurations/agent_configuration_create_edit/settings_page/settings_page.tsx +++ b/x-pack/plugins/apm/public/components/app/settings/agent_configurations/agent_configuration_create_edit/settings_page/settings_page.tsx @@ -6,24 +6,20 @@ */ import { - EuiBottomBar, EuiButton, - EuiButtonEmpty, EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiForm, - EuiHealth, + EuiHorizontalRule, EuiLoadingSpinner, EuiSpacer, EuiStat, - EuiText, - EuiHorizontalRule, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useUiTracker } from '@kbn/observability-plugin/public'; import React, { useMemo, useState } from 'react'; import { useHistory } from 'react-router-dom'; -import { useUiTracker } from '@kbn/observability-plugin/public'; import { getOptionLabel } from '../../../../../../../common/agent_configuration/all_option'; import { AgentConfigurationIntake } from '../../../../../../../common/agent_configuration/configuration_types'; import { @@ -34,6 +30,7 @@ import { import { AgentName } from '../../../../../../../typings/es_schemas/ui/fields/agent'; import { useApmPluginContext } from '../../../../../../context/apm_plugin/use_apm_plugin_context'; import { FETCH_STATUS } from '../../../../../../hooks/use_fetcher'; +import { BottomBarActions } from '../../../bottom_bar_actions'; import { saveConfig } from './save_config'; import { SettingFormRow } from './setting_form_row'; @@ -190,53 +187,16 @@ export function SettingsPage({ {/* Bottom bar with save button */} {unsavedChangesCount > 0 && ( - - - - - - {i18n.translate('xpack.apm.unsavedChanges', { - defaultMessage: - '{unsavedChangesCount, plural, =0{0 unsaved changes} one {1 unsaved change} other {# unsaved changes}} ', - values: { unsavedChangesCount }, - })} - - - - - - - {i18n.translate( - 'xpack.apm.agentConfig.settingsPage.discardChangesButton', - { defaultMessage: 'Discard changes' } - )} - - - - - {i18n.translate( - 'xpack.apm.agentConfig.settingsPage.saveButton', - { defaultMessage: 'Save configuration' } - )} - - - - - - + )} ); diff --git a/x-pack/plugins/apm/public/components/app/settings/bottom_bar_actions/index.tsx b/x-pack/plugins/apm/public/components/app/settings/bottom_bar_actions/index.tsx new file mode 100644 index 0000000000000..85ee597b754ec --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/settings/bottom_bar_actions/index.tsx @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiBottomBar, + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiHealth, + EuiText, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; + +interface Props { + unsavedChangesCount: number; + isLoading: boolean; + onDiscardChanges: () => void; + onSave: () => void; + saveLabel: string; +} + +export function BottomBarActions({ + isLoading, + onDiscardChanges, + onSave, + unsavedChangesCount, + saveLabel, +}: Props) { + return ( + + + + + + {i18n.translate('xpack.apm.bottomBarActions.unsavedChanges', { + defaultMessage: + '{unsavedChangesCount, plural, =0{0 unsaved changes} one {1 unsaved change} other {# unsaved changes}} ', + values: { unsavedChangesCount }, + })} + + + + + + + {i18n.translate( + 'xpack.apm.bottomBarActions.discardChangesButton', + { + defaultMessage: 'Discard changes', + } + )} + + + + + {saveLabel} + + + + + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx b/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx index ef41b75aedeaf..d8e62397626f8 100644 --- a/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx +++ b/x-pack/plugins/apm/public/components/app/settings/general_settings/index.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import { EuiButton } from '@elastic/eui'; import { LazyField } from '@kbn/advanced-settings-plugin/public'; import { i18n } from '@kbn/i18n'; import { @@ -20,6 +19,7 @@ import { isEmpty } from 'lodash'; import React from 'react'; import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context'; import { useApmEditableSettings } from '../../../../hooks/use_apm_editable_settings'; +import { BottomBarActions } from '../bottom_bar_actions'; const apmSettingsKeys = [ enableComparisonByDefault, @@ -38,6 +38,7 @@ export function GeneralSettings() { unsavedChanges, saveAll, isSaving, + cleanUnsavedChanges, } = useApmEditableSettings(apmSettingsKeys); async function handleSave() { @@ -76,16 +77,17 @@ export function GeneralSettings() { /> ); })} - - {i18n.translate('xpack.apm.labs.reload', { - defaultMessage: 'Reload to apply changes', - })} - + {!isEmpty(unsavedChanges) && ( + + )} ); } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 270aba534f81b..70333f960f0ff 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -6561,7 +6561,6 @@ "xpack.apm.tutorial.specProvider.longDescription": "Le monitoring des performances applicatives (APM) collecte les indicateurs et les erreurs de performance approfondies depuis votre application. Cela vous permet de monitorer les performances de milliers d'applications en temps réel. [Learn more]({learnMoreLink}).", "xpack.apm.tutorial.windowsServerInstructions.textPost": "Remarque : si l'exécution du script est désactivée dans votre système, vous devez définir la politique d'exécution de la session en cours de sorte que l'exécution du script soit autorisée. Par exemple : {command}.", "xpack.apm.tutorial.windowsServerInstructions.textPre": "1. Téléchargez le fichier zip APM Server Windows depuis [Download page]({downloadPageLink}).\n2. Extrayez le contenu du fichier zip dans {zipFileExtractFolder}.\n3. Renommez le répertoire {apmServerDirectory} en \"APM-Server\".\n4. Ouvrez une invite PowerShell en tant qu'administrateur (faites un clic droit sur l'icône PowerShell et sélectionnez **Exécuter en tant qu'administrateur**). Si vous exécutez Windows XP, vous devrez peut-être télécharger et installer PowerShell.\n5. Dans l'invite PowerShell, exécutez les commandes suivantes pour installer le serveur APM en tant que service Windows :", - "xpack.apm.unsavedChanges": "{unsavedChangesCount, plural, =0{0 modification non enregistrée} one {1 modification non enregistrée} other {# modifications non enregistrées}} ", "xpack.apm.waterfall.errorCount": "{errorCount, plural, one {Afficher l'erreur liée} other {Afficher # erreurs liées}}", "xpack.apm.waterfall.spanLinks.badge": "{total} {total, plural, one {lien d'intervalle} other {liens d'intervalle}}", "xpack.apm.waterfall.spanLinks.tooltip.linkedChildren": "{linkedChildren} entrants", @@ -6635,7 +6634,6 @@ "xpack.apm.agentConfig.servicePage.service.fieldLabel": "Nom de service", "xpack.apm.agentConfig.servicePage.service.placeholder": "Sélectionner une option", "xpack.apm.agentConfig.servicePage.service.title": "Service", - "xpack.apm.agentConfig.settingsPage.discardChangesButton": "Abandonner les modifications", "xpack.apm.agentConfig.settingsPage.notFound.message": "La configuration demandée n'existe pas", "xpack.apm.agentConfig.settingsPage.notFound.title": "Désolé, une erreur est survenue", "xpack.apm.agentConfig.settingsPage.saveButton": "Enregistrer la configuration", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b24713361e882..066d96ec83797 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6549,7 +6549,6 @@ "xpack.apm.tutorial.specProvider.longDescription": "アプリケーションパフォーマンスモニタリング(APM)は、アプリケーション内から詳細なパフォーマンスメトリックやエラーを収集します。何千ものアプリケーションのパフォーマンスをリアルタイムで監視できます。[詳細]({learnMoreLink})。", "xpack.apm.tutorial.windowsServerInstructions.textPost": "注:システムでスクリプトの実行が無効な場合、スクリプトを実行するために現在のセッションの実行ポリシーの設定が必要となります。例:{command}。", "xpack.apm.tutorial.windowsServerInstructions.textPre": "1.[ダウンロードページ]({downloadPageLink})から APM Server Windows zip ファイルをダウンロードします。\n2.zip ファイルの内容を {zipFileExtractFolder} に抽出します。\n3.「{apmServerDirectory} ディレクトリの名前を「APM-Server」に変更します。\n4.管理者としてPowerShellプロンプトを開きます(PowerShellアイコンを右クリックして「管理者として実行」を選択します)。Windows XPをご使用の場合、PowerShellのダウンロードとインストールが必要な場合があります。\n5.PowerShell プロンプトで次のコマンドを実行し、APM Server を Windows サービスとしてインストールします。", - "xpack.apm.unsavedChanges": "{unsavedChangesCount, plural, other {# 未保存変更}} ", "xpack.apm.waterfall.errorCount": "{errorCount, plural, one {関連するエラーを表示} other {View # 件の関連するエラーを表示}}", "xpack.apm.waterfall.spanLinks.badge": "{total} {total, plural, other {個のスパンリンク}}", "xpack.apm.waterfall.spanLinks.tooltip.linkedChildren": "{linkedChildren}受信", @@ -6623,7 +6622,6 @@ "xpack.apm.agentConfig.servicePage.service.fieldLabel": "サービス名", "xpack.apm.agentConfig.servicePage.service.placeholder": "オプションを選択", "xpack.apm.agentConfig.servicePage.service.title": "サービス", - "xpack.apm.agentConfig.settingsPage.discardChangesButton": "変更を破棄", "xpack.apm.agentConfig.settingsPage.notFound.message": "リクエストされた構成が存在しません", "xpack.apm.agentConfig.settingsPage.notFound.title": "申し訳ございません、エラーが発生しました", "xpack.apm.agentConfig.settingsPage.saveButton": "構成を保存", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 313c4fc3b9185..d44b85a0ff1a3 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6562,7 +6562,6 @@ "xpack.apm.tutorial.specProvider.longDescription": "应用程序性能监测 (APM) 从您的应用程序内收集深入全面的性能指标和错误。其允许您实时监测数以千计的应用程序的性能。[了解详情]({learnMoreLink})。", "xpack.apm.tutorial.windowsServerInstructions.textPost": "注意:如果您的系统禁用了脚本执行,则需要为当前会话设置执行策略,以允许脚本运行。示例:{command}。", "xpack.apm.tutorial.windowsServerInstructions.textPre": "1.从[下载页面]({downloadPageLink})下载 APM Server Windows zip 文件。\n2.将 zip 文件的内容解压缩到 {zipFileExtractFolder}。\n3.将 {apmServerDirectory} 目录重命名为 `APM-Server`。\n4.以管理员身份打开 PowerShell 提示符(右键单击 PowerShell 图标,然后选择**以管理员身份运行**)。如果运行的是 Windows XP,则可能需要下载并安装 PowerShell。\n5.从 PowerShell 提示符处,运行以下命令以将 APM Server 安装为 Windows 服务:", - "xpack.apm.unsavedChanges": "{unsavedChangesCount, plural, =0{0 个未保存更改} one {1 个未保存更改} other {# 个未保存更改}} ", "xpack.apm.waterfall.errorCount": "{errorCount, plural, one {查看相关错误} other {查看 # 个相关错误}}", "xpack.apm.waterfall.spanLinks.badge": "{total} 个{total, plural, other {跨度链接}}", "xpack.apm.waterfall.spanLinks.tooltip.linkedChildren": "{linkedChildren} 传入", @@ -6636,7 +6635,6 @@ "xpack.apm.agentConfig.servicePage.service.fieldLabel": "服务名称", "xpack.apm.agentConfig.servicePage.service.placeholder": "选择选项", "xpack.apm.agentConfig.servicePage.service.title": "服务", - "xpack.apm.agentConfig.settingsPage.discardChangesButton": "放弃更改", "xpack.apm.agentConfig.settingsPage.notFound.message": "请求的配置不存在", "xpack.apm.agentConfig.settingsPage.notFound.title": "抱歉,有错误", "xpack.apm.agentConfig.settingsPage.saveButton": "保存配置", From 99e367446bd7512b3826e8a1e002a23f7e187be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 20 Sep 2022 20:17:23 -0400 Subject: [PATCH 27/55] [APM] Add AWS Lambda metrics to "Metrics" tab UI (#140550) * [APM] AWS lambda metrics api * fixing typo * fixing duration * fixing * tests * addressing pr comments * yformater time * tests * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * addressing pr comments * addressing PR comments * fixing compute usage * fixing ci * fixing ci * addressing PR comments * fixing synthtrace * refactoring * showing metrics tab * synthtrace * addressing pr comments * adding beta badge * fixing tests * fixing active instaces query * addressing PR comments * fixing calc * fixing * removing merge conflic * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * addressing PR changes * remiving unused import * adding feature flag Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../server/collectors/management/schema.ts | 4 ++ .../server/collectors/management/types.ts | 1 + src/plugins/telemetry/schema/oss_plugins.json | 8 +++- .../templates/apm_service_template/index.tsx | 31 ++++++++++++---- .../shared/charts/metrics_chart/index.tsx | 21 +++++++++-- .../shared/charts/timeseries_chart.tsx | 14 ++++++- .../use_service_metric_charts_fetcher.ts | 14 ++++++- .../by_agent/serverless/active_instances.ts | 14 +++++-- .../by_agent/serverless/cold_start_count.ts | 6 ++- .../serverless/cold_start_duration.ts | 9 +++++ .../by_agent/serverless/compute_usage.ts | 37 +++++++------------ .../metrics/by_agent/serverless/index.ts | 2 +- .../serverless/serverless_function_latency.ts | 7 ++++ .../metrics/fetch_and_transform_metrics.ts | 23 ++++++++++-- .../apm/server/routes/metrics/route.ts | 15 +------- .../apm/server/routes/metrics/types.ts | 1 + x-pack/plugins/apm/typings/timeseries.ts | 2 +- x-pack/plugins/observability/common/index.ts | 1 + .../observability/common/ui_settings_keys.ts | 1 + .../observability/server/ui_settings.ts | 23 ++++++++++++ 20 files changed, 171 insertions(+), 63 deletions(-) diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index b20d0a7c3f3bd..cc80adc4cb463 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -522,6 +522,10 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, + 'observability:enableAwsLambdaMetrics': { + type: 'boolean', + _meta: { description: 'Non-default value of setting.' }, + }, 'observability:apmProgressiveLoading': { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index f6aaf1258c818..924649351d988 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -141,6 +141,7 @@ export interface UsageStats { 'metrics:allowCheckingForFailedShards': boolean; 'observability:apmOperationsTab': boolean; 'observability:apmLabsButton': boolean; + 'observability:enableAwsLambdaMetrics': boolean; 'observability:apmProgressiveLoading': string; 'observability:apmServiceGroupMaxNumberOfServices': number; 'observability:apmServiceInventoryOptimizedSorting': boolean; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 30e476afd20cf..a1ddc4ee56040 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -8828,6 +8828,12 @@ "description": "Non-default value of setting." } }, + "observability:enableAwsLambdaMetrics": { + "type": "boolean", + "_meta": { + "description": "Non-default value of setting." + } + }, "observability:apmProgressiveLoading": { "type": "keyword", "_meta": { @@ -10317,4 +10323,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx index 9622acb525618..3f84a4bdb1347 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx @@ -14,10 +14,11 @@ import { import { i18n } from '@kbn/i18n'; import { omit } from 'lodash'; import React from 'react'; +import { enableAwsLambdaMetrics } from '@kbn/observability-plugin/common'; import { - isMobileAgentName, isJavaAgentName, isJRubyAgent, + isMobileAgentName, isRumAgentName, isServerlessAgent, } from '../../../../../common/agent_name'; @@ -29,13 +30,13 @@ import { ServiceAnomalyTimeseriesContextProvider } from '../../../../context/ser import { useApmParams } from '../../../../hooks/use_apm_params'; import { useApmRouter } from '../../../../hooks/use_apm_router'; import { useTimeRange } from '../../../../hooks/use_time_range'; +import { getAlertingCapabilities } from '../../../alerting/get_alerting_capabilities'; +import { BetaBadge } from '../../../shared/beta_badge'; import { SearchBar } from '../../../shared/search_bar'; import { ServiceIcons } from '../../../shared/service_icons'; +import { TechnicalPreviewBadge } from '../../../shared/technical_preview_badge'; import { ApmMainTemplate } from '../apm_main_template'; import { AnalyzeDataButton } from './analyze_data_button'; -import { getAlertingCapabilities } from '../../../alerting/get_alerting_capabilities'; -import { BetaBadge } from '../../../shared/beta_badge'; -import { TechnicalPreviewBadge } from '../../../shared/technical_preview_badge'; type Tab = NonNullable[0] & { key: @@ -139,17 +140,21 @@ function TemplateWithContext({ export function isMetricsTabHidden({ agentName, runtimeName, + isAwsLambdaEnabled, }: { agentName?: string; runtimeName?: string; + isAwsLambdaEnabled?: boolean; }) { + if (isServerlessAgent(runtimeName)) { + return !isAwsLambdaEnabled; + } return ( !agentName || isRumAgentName(agentName) || isJavaAgentName(agentName) || isMobileAgentName(agentName) || - isJRubyAgent(agentName, runtimeName) || - isServerlessAgent(runtimeName) + isJRubyAgent(agentName, runtimeName) ); } @@ -192,6 +197,11 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { const router = useApmRouter(); + const isAwsLambdaEnabled = core.uiSettings.get( + enableAwsLambdaMetrics, + true + ); + const { path: { serviceName }, query: queryFromUrl, @@ -257,7 +267,14 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { label: i18n.translate('xpack.apm.serviceDetails.metricsTabLabel', { defaultMessage: 'Metrics', }), - hidden: isMetricsTabHidden({ agentName, runtimeName }), + append: isServerlessAgent(runtimeName) ? ( + + ) : undefined, + hidden: isMetricsTabHidden({ + agentName, + runtimeName, + isAwsLambdaEnabled, + }), }, { key: 'nodes', diff --git a/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx index 1ad5227813d54..41ad3acda28a0 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/metrics_chart/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiTitle } from '@elastic/eui'; import React from 'react'; import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; import { @@ -60,9 +60,22 @@ interface Props { export function MetricsChart({ chart, fetchStatus }: Props) { return ( <> - - {chart.title} - + + + + {chart.title} + + + {chart.description && ( + + + + )} + {allSeries.map((serie) => { - const Series = serie.type === 'area' ? AreaSeries : LineSeries; + const Series = getChartType(serie.type); return ( ({ diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts index fc94a59da9a22..d884aa8dce446 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { termQuery } from '@kbn/observability-plugin/server'; +import { euiLightVars as theme } from '@kbn/ui-theme'; import { FAAS_COLDSTART, METRICSET_NAME, @@ -20,13 +21,14 @@ const chartBase: ChartBase = { defaultMessage: 'Cold start', }), key: 'cold_start_count', - type: 'linemark', - yUnit: 'number', + type: 'bar', + yUnit: 'integer', series: { coldStart: { title: i18n.translate('xpack.apm.agentMetrics.serverless.coldStart', { defaultMessage: 'Cold start', }), + color: theme.euiColorVis5, }, }, }; diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts index 84fac7f99303e..e66d855d1be99 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { euiLightVars as theme } from '@kbn/ui-theme'; import { FAAS_COLDSTART_DURATION } from '../../../../../common/elasticsearch_fieldnames'; import { Setup } from '../../../../lib/helpers/setup_request'; import { fetchAndTransformMetrics } from '../../fetch_and_transform_metrics'; @@ -24,8 +25,16 @@ const chartBase: ChartBase = { 'xpack.apm.agentMetrics.serverless.coldStartDuration', { defaultMessage: 'Cold start duration' } ), + color: theme.euiColorVis5, }, }, + description: i18n.translate( + 'xpack.apm.agentMetrics.serverless.coldStartDuration.description', + { + defaultMessage: + 'Cold start duration shows the execution duration of the serverless runtime for requests that experience cold starts.', + } + ), }; export function getColdStartDuration({ diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts index da57498c8af02..b38e0665a77f2 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts @@ -21,27 +21,9 @@ import { } from '../../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../../common/utils/environment_query'; import { isFiniteNumber } from '../../../../../common/utils/is_finite_number'; -import { getVizColorForIndex } from '../../../../../common/viz_colors'; import { getMetricsDateHistogramParams } from '../../../../lib/helpers/metrics'; import { Setup } from '../../../../lib/helpers/setup_request'; import { GenericMetricsChart } from '../../fetch_and_transform_metrics'; -import { ChartBase } from '../../types'; - -const chartBase: ChartBase = { - title: i18n.translate('xpack.apm.agentMetrics.serverless.computeUsage', { - defaultMessage: 'Compute usage', - }), - key: 'compute_usage', - type: 'linemark', - yUnit: 'number', - series: { - computeUsage: { - title: i18n.translate('xpack.apm.agentMetrics.serverless.computeUsage', { - defaultMessage: 'Compute usage', - }), - }, - }, -}; /** * To calculate the compute usage we need to multiply the "system.memory.total" by "faas.billed_duration". @@ -126,9 +108,18 @@ export async function getComputeUsage({ const timeseriesData = aggregations?.timeseriesData; return { - title: chartBase.title, - key: chartBase.key, - yUnit: chartBase.yUnit, + title: i18n.translate('xpack.apm.agentMetrics.serverless.computeUsage', { + defaultMessage: 'Compute usage', + }), + key: 'compute_usage', + yUnit: 'number', + description: i18n.translate( + 'xpack.apm.agentMetrics.serverless.computeUsage.description', + { + defaultMessage: + "Compute usage (in GB-seconds) is the execution time multiplied by the available memory size of your function's instances. The compute usage is a direct indicator for the costs of your serverless function.", + } + ), series: !timeseriesData || timeseriesData.buckets.length === 0 ? [] @@ -139,12 +130,12 @@ export async function getComputeUsage({ { defaultMessage: 'Compute usage' } ), key: 'compute_usage', - type: 'linemark', + type: 'bar', overallValue: calculateComputeUsageGBSeconds({ faasBilledDuration: aggregations?.avgFaasBilledDuration.value, totalMemory: aggregations?.avgTotalMemory.value, }), - color: getVizColorForIndex(0, theme), + color: theme.euiColorVis0, data: timeseriesData.buckets.map((bucket) => { const computeUsage = calculateComputeUsageGBSeconds({ faasBilledDuration: bucket.avgFaasBilledDuration.value, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts index a34165dc95f41..9200e9d07e1ce 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts @@ -51,9 +51,9 @@ export function getServerlessAgentMetricCharts({ ...options, searchAggregatedTransactions, }), + getMemoryChartData(options), getColdStartDuration(options), getColdStartCount(options), - getMemoryChartData(options), getComputeUsage(options), getActiveInstances({ ...options, searchAggregatedTransactions }), ]); diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts index 99a09c86e954f..0db9385615d2a 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts @@ -32,6 +32,13 @@ const chartBase: ChartBase = { type: 'linemark', yUnit: 'time', series: {}, + description: i18n.translate( + 'xpack.apm.agentMetrics.serverless.avgDuration.description', + { + defaultMessage: + 'Transaction duration is the time spent processing and responding to a request. If the request is queued it will not be contribute to the transaction duration but will contribute the overall billed duration', + } + ), }; async function getServerlessLantecySeries({ diff --git a/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts b/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts index 9bc5fe20a72c8..b8faa6b140a4b 100644 --- a/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts +++ b/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts @@ -21,6 +21,7 @@ import { serviceNodeNameQuery, } from '../../../common/utils/environment_query'; import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; +import { ChartType, Coordinate, YUnit } from '../../../typings/timeseries'; type MetricsAggregationMap = Unionize<{ min: AggregationOptionsByType['min']; @@ -42,9 +43,22 @@ export type GenericMetricsRequest = APMEventESSearchRequest & { }; }; -export type GenericMetricsChart = Awaited< - ReturnType ->; +export type GenericMetricsChart = Awaited; + +export interface FetchAndTransformMetrics { + title: string; + key: string; + yUnit: YUnit; + series: Array<{ + title: string; + key: string; + type: ChartType; + color: string; + overallValue: number; + data: Coordinate[]; + }>; + description?: string; +} export async function fetchAndTransformMetrics({ environment, @@ -70,7 +84,7 @@ export async function fetchAndTransformMetrics({ aggs: T; additionalFilters?: QueryDslQueryContainer[]; operationName: string; -}) { +}): Promise { const { apmEventClient, config } = setup; const params: GenericMetricsRequest = { @@ -115,6 +129,7 @@ export async function fetchAndTransformMetrics({ title: chartBase.title, key: chartBase.key, yUnit: chartBase.yUnit, + description: chartBase.description, series: hits.total.value === 0 ? [] diff --git a/x-pack/plugins/apm/server/routes/metrics/route.ts b/x-pack/plugins/apm/server/routes/metrics/route.ts index f8b20ae4e0299..5d6b4f245c568 100644 --- a/x-pack/plugins/apm/server/routes/metrics/route.ts +++ b/x-pack/plugins/apm/server/routes/metrics/route.ts @@ -9,6 +9,7 @@ import * as t from 'io-ts'; import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; +import { FetchAndTransformMetrics } from './fetch_and_transform_metrics'; import { getMetricsChartDataByAgent } from './get_metrics_chart_data_by_agent'; const metricsChartsRoute = createApmServerRoute({ @@ -34,19 +35,7 @@ const metricsChartsRoute = createApmServerRoute({ handler: async ( resources ): Promise<{ - charts: Array<{ - title: string; - key: string; - yUnit: import('./../../../typings/timeseries').YUnit; - series: Array<{ - title: string; - key: string; - type: import('./../../../typings/timeseries').ChartType; - color: string; - overallValue: number; - data: Array<{ x: number; y: number | null }>; - }>; - }>; + charts: FetchAndTransformMetrics[]; }> => { const { params } = resources; const setup = await setupRequest(resources); diff --git a/x-pack/plugins/apm/server/routes/metrics/types.ts b/x-pack/plugins/apm/server/routes/metrics/types.ts index 92ca587e3bdff..0cbf1cfce0916 100644 --- a/x-pack/plugins/apm/server/routes/metrics/types.ts +++ b/x-pack/plugins/apm/server/routes/metrics/types.ts @@ -18,4 +18,5 @@ export interface ChartBase { color?: string; }; }; + description?: string; } diff --git a/x-pack/plugins/apm/typings/timeseries.ts b/x-pack/plugins/apm/typings/timeseries.ts index b675873fc1d3c..2b2af4f3bff06 100644 --- a/x-pack/plugins/apm/typings/timeseries.ts +++ b/x-pack/plugins/apm/typings/timeseries.ts @@ -69,5 +69,5 @@ export interface APMChartSpec< groupId?: string; } -export type ChartType = 'area' | 'linemark'; +export type ChartType = 'area' | 'linemark' | 'bar'; export type YUnit = 'percent' | 'bytes' | 'number' | 'time' | 'integer'; diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index 78262d806bb46..e4a36b379ff49 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -25,6 +25,7 @@ export { apmOperationsTab, apmLabsButton, enableInfrastructureHostsView, + enableAwsLambdaMetrics, } from './ui_settings_keys'; export { diff --git a/x-pack/plugins/observability/common/ui_settings_keys.ts b/x-pack/plugins/observability/common/ui_settings_keys.ts index d413cd5d79d13..8167c9a2c5ef5 100644 --- a/x-pack/plugins/observability/common/ui_settings_keys.ts +++ b/x-pack/plugins/observability/common/ui_settings_keys.ts @@ -20,3 +20,4 @@ export const apmTraceExplorerTab = 'observability:apmTraceExplorerTab'; export const apmOperationsTab = 'observability:apmOperationsTab'; export const apmLabsButton = 'observability:apmLabsButton'; export const enableInfrastructureHostsView = 'observability:enableInfrastructureHostsView'; +export const enableAwsLambdaMetrics = 'observability:enableAwsLambdaMetrics'; diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 6775a7cf51029..21296a9b3e35a 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -23,6 +23,7 @@ import { apmOperationsTab, apmLabsButton, enableInfrastructureHostsView, + enableAwsLambdaMetrics, } from '../common/ui_settings_keys'; const technicalPreviewLabel = i18n.translate( @@ -254,4 +255,26 @@ export const uiSettings: Record = { }), schema: schema.boolean(), }, + [enableAwsLambdaMetrics]: { + category: [observabilityFeatureId], + name: i18n.translate('xpack.observability.enableAwsLambdaMetrics', { + defaultMessage: 'AWS Lambda Metrics', + }), + description: i18n.translate('xpack.observability.enableAwsLambdaMetricsDescription', { + defaultMessage: 'Display Amazon Lambda metrics in the service metrics tab. {feedbackLink}', + values: { + feedbackLink: + '' + + i18n.translate('xpack.observability.awsLambdaDescription', { + defaultMessage: 'Send feedback', + }) + + '', + }, + }), + schema: schema.boolean(), + value: true, + requiresPageReload: true, + type: 'boolean', + showInLabs: true, + }, }; From 4c0c0db9c5309d5b63a644d627596961c7e7b5e1 Mon Sep 17 00:00:00 2001 From: Paulo Henrique Date: Tue, 20 Sep 2022 17:22:32 -0700 Subject: [PATCH 28/55] [8.5][Session view][TTY output] UI Improvements (#141175) --- .../public/components/tty_player/styles.ts | 2 +- .../components/tty_player_controls/index.tsx | 30 ++++---- .../tty_player_controls_markers/index.tsx | 69 +++++++++++-------- .../tty_player_controls_markers/styles.ts | 31 +++++++-- .../components/tty_text_sizer/index.tsx | 37 +++++++--- .../components/tty_text_sizer/styles.ts | 3 +- .../components/tty_text_sizer/translations.ts | 2 +- 7 files changed, 110 insertions(+), 64 deletions(-) diff --git a/x-pack/plugins/session_view/public/components/tty_player/styles.ts b/x-pack/plugins/session_view/public/components/tty_player/styles.ts index 91852d3d02b90..2055add14c914 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/styles.ts +++ b/x-pack/plugins/session_view/public/components/tty_player/styles.ts @@ -75,7 +75,7 @@ export const useStyles = (tty?: Teletype, show?: boolean) => { transform: `translateY(${show ? 0 : '100%'})`, transition: 'transform .2s', width: '100%', - height: 'calc(100% - 120px)', + height: 'calc(100% - 112px)', overflow: 'auto', backgroundColor: colors.ink, }; diff --git a/x-pack/plugins/session_view/public/components/tty_player_controls/index.tsx b/x-pack/plugins/session_view/public/components/tty_player_controls/index.tsx index fffb7493f4c9e..58709d92772f7 100644 --- a/x-pack/plugins/session_view/public/components/tty_player_controls/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player_controls/index.tsx @@ -12,6 +12,7 @@ import { EuiFlexItem, EuiButtonIcon, EuiToolTip, + EuiButtonIconProps, } from '@elastic/eui'; import { findIndex } from 'lodash'; import { ProcessStartMarker, ProcessEvent } from '../../../common/types/process_tree'; @@ -54,6 +55,13 @@ export const TTYPlayerControls = ({ }: TTYPlayerControlsDeps) => { const styles = useStyles(); + const commonButtonProps: Partial = { + display: 'empty', + size: 's', + color: 'ghost', + css: styles.controlButton, + }; + const onLineChange = useCallback( (event: ChangeEvent | MouseEvent) => { const line = parseInt((event?.target as HTMLInputElement).value || '0', 10); @@ -111,65 +119,55 @@ export const TTYPlayerControls = ({ @@ -179,6 +177,7 @@ export const TTYPlayerControls = ({ linesLength={linesLength} currentLine={currentLine} onChange={onLineChange} + onSeekLine={onSeekLine} />
@@ -188,6 +187,7 @@ export const TTYPlayerControls = ({ onClick={handleViewInSession} iconType="arrowRight" aria-label={VIEW_IN_SESSION} + color="ghost" > {VIEW_IN_SESSION} diff --git a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx index 2eb0c0b3ecf88..e0d2f7b140d5f 100644 --- a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx @@ -6,7 +6,7 @@ */ import React, { ChangeEvent, MouseEvent, useMemo } from 'react'; -import { EuiRange } from '@elastic/eui'; +import { EuiRange, EuiToolTip } from '@elastic/eui'; import type { ProcessStartMarker } from '../../../../common/types/process_tree'; import { useStyles } from './styles'; import { PlayHead } from './play_head'; @@ -16,11 +16,13 @@ type Props = { linesLength: number; currentLine: number; onChange: (e: ChangeEvent | MouseEvent) => void; + onSeekLine(line: number): void; }; type TTYPlayerLineMarker = { line: number; type: 'output' | 'data_limited'; + name: string; }; export const TTYPlayerControlsMarkers = ({ @@ -28,8 +30,11 @@ export const TTYPlayerControlsMarkers = ({ linesLength, currentLine, onChange, + onSeekLine, }: Props) => { - const styles = useStyles(); + const progress = useMemo(() => (currentLine / linesLength) * 100, [currentLine, linesLength]); + + const styles = useStyles(progress); const markers = useMemo(() => { if (processStartMarkers.length < 1) { @@ -41,22 +46,29 @@ export const TTYPlayerControlsMarkers = ({ type: event.process?.io?.max_bytes_per_process_exceeded === true ? 'data_limited' : 'output', line, + name: event.process?.name, } as TTYPlayerLineMarker) ); }, [processStartMarkers]); const markersLength = markers.length; + + const currentSelectedType = useMemo(() => { + if (!markersLength) { + return undefined; + } + const currentSelected = + currentLine >= markers[markersLength - 1].line + ? markersLength - 1 + : markers.findIndex((marker) => marker.line > currentLine) - 1; + + return markers[Math.max(0, currentSelected)].type; + }, [currentLine, markers, markersLength]); + if (!markersLength) { return null; } - const currentSelected = - currentLine >= markers[markersLength - 1].line - ? markersLength - 1 - : markers.findIndex((marker) => marker.line > currentLine) - 1; - - const currentSelectedType = markers[Math.max(0, currentSelected)].type; - return ( <> - +
- {markers.map(({ line, type }, idx) => { + {markers.map(({ line, type, name }, idx) => { const selected = currentLine >= line && (idx === markersLength - 1 || currentLine < markers[idx + 1].line); // markers positions are absolute, setting higher z-index on the selected one in case there // are severals next to each other - const style = { - left: `${(line * 100) / linesLength}%`, + const markerWrapperPositioning = { + left: `${(line / linesLength) * 100}%`, zIndex: selected ? 3 : 2, }; + const onMarkerClick = () => onSeekLine(line); + return ( - +
+ + + +
); })}
diff --git a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts index 58f6d2b01afa6..b9af9f4ec0331 100644 --- a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts +++ b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts @@ -11,7 +11,7 @@ import { useEuiTheme } from '../../../hooks'; type TTYPlayerLineMarkerType = 'output' | 'data_limited'; -export const useStyles = () => { +export const useStyles = (progress: number) => { const { euiTheme, euiVars } = useEuiTheme(); const cached = useMemo(() => { const { border } = euiTheme; @@ -23,6 +23,12 @@ export const useStyles = () => { width: '100%', }; + const markerWrapper: CSSObject = { + position: 'absolute', + top: 0, + lineHeight: 0, + }; + const getMarkerBackgroundColor = (type: TTYPlayerLineMarkerType, selected: boolean) => { if (type === 'data_limited') { return euiVars.terminalOutputMarkerWarning; @@ -36,7 +42,6 @@ export const useStyles = () => { const marker = (type: TTYPlayerLineMarkerType, selected: boolean): CSSObject => ({ fontSize: 0, overflow: 'hidden', - position: 'absolute', padding: 0, width: 3, height: 12, @@ -44,10 +49,8 @@ export const useStyles = () => { border: `${border.width.thick} solid ${euiVars.terminalOutputBackground}`, borderRadius: border.radius.small, boxSizing: 'content-box', - top: 0, - pointerEvents: 'none', marginLeft: '-3.5px', - transition: 'left .5s ease-in-out .3s', + transition: 'left .5s ease-in-out', }); const playHeadThumb: CSSObject = { @@ -82,6 +85,9 @@ export const useStyles = () => { "input[type='range']::-moz-range-thumb": customThumb, '.euiRangeHighlight__progress': { backgroundColor: euiVars.euiColorVis0_behindText, + width: progress + '%', + borderBottomRightRadius: 0, + borderTopRightRadius: 0, }, '.euiRangeSlider:focus ~ .euiRangeHighlight .euiRangeHighlight__progress': { backgroundColor: euiVars.euiColorVis0_behindText, @@ -93,9 +99,10 @@ export const useStyles = () => { }, }; - const playHead = (type: TTYPlayerLineMarkerType): CSSObject => ({ + const playHead = (type?: TTYPlayerLineMarkerType): CSSObject => ({ ...playHeadThumb, position: 'absolute', + left: progress + '%', top: 16, fill: type === 'data_limited' @@ -105,11 +112,21 @@ export const useStyles = () => { return { marker, + markerWrapper, markersOverlay, range, playHead, }; - }, [euiTheme, euiVars]); + }, [ + euiTheme, + euiVars.euiColorVis0_behindText, + euiVars.euiColorVis1, + euiVars.terminalOutputBackground, + euiVars.terminalOutputMarkerAccent, + euiVars.terminalOutputMarkerWarning, + euiVars.terminalOutputSliderBackground, + progress, + ]); return cached; }; diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx index 44c4f6801d3ba..42531fc7f5e6c 100644 --- a/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/index.tsx @@ -5,7 +5,13 @@ * 2.0. */ import React, { useCallback, useEffect, useState } from 'react'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { + EuiButtonIcon, + EuiButtonIconProps, + EuiFlexGroup, + EuiFlexItem, + EuiToolTip, +} from '@elastic/eui'; import { Teletype } from '../../../common/types/process_tree'; import { DEFAULT_TTY_FONT_SIZE } from '../../../common/constants'; import { ZOOM_IN, ZOOM_FIT, ZOOM_OUT } from './translations'; @@ -19,6 +25,12 @@ export interface TTYTextSizerDeps { onFontSizeChanged(newSize: number): void; } +const commonButtonProps: Partial = { + display: 'empty', + size: 's', + color: 'ghost', +}; + const LINE_HEIGHT_SCALE_RATIO = 1.3; const MINIMUM_FONT_SIZE = 2; const MAXIMUM_FONT_SIZE = 20; @@ -88,6 +100,7 @@ export const TTYTextSizer = ({ display={fit ? 'fill' : 'empty'} iconType={fit ? 'expand' : 'minimize'} onClick={onToggleFit} + {...commonButtonProps} />
@@ -95,12 +108,13 @@ export const TTYTextSizer = ({
- + @@ -108,12 +122,13 @@ export const TTYTextSizer = ({ {`${Math.round((fontSize / DEFAULT_TTY_FONT_SIZE) * 100)}%`} - + diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/styles.ts b/x-pack/plugins/session_view/public/components/tty_text_sizer/styles.ts index d233626c1de66..7cc47374f5434 100644 --- a/x-pack/plugins/session_view/public/components/tty_text_sizer/styles.ts +++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/styles.ts @@ -16,14 +16,13 @@ export const useStyles = () => { const ratio: CSSObject = { fontSize: size.m, + color: colors.ghost, }; const separator: CSSObject = { background: colors.lightShade, height: size.xl, width: border.width.thin, - marginLeft: size.xs, - marginRight: size.xs, }; return { diff --git a/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts b/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts index 0bec7775d43c5..96e5d9d006dea 100644 --- a/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts +++ b/x-pack/plugins/session_view/public/components/tty_text_sizer/translations.ts @@ -11,7 +11,7 @@ export const ZOOM_IN = i18n.translate('xpack.sessionView.zoomIn', { }); export const ZOOM_FIT = i18n.translate('xpack.sessionView.zoomFit', { - defaultMessage: 'Zoom fit', + defaultMessage: 'Fit screen', }); export const ZOOM_OUT = i18n.translate('xpack.sessionView.zoomOut', { From 0aa74edd2e0e63a39347c5fafbd9f55a79eff215 Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Tue, 20 Sep 2022 21:23:06 -0300 Subject: [PATCH 29/55] [Discover] Persist histogram height to local storage (#140997) * [Discover] Initial work to persist histogram height * [Discover] Fix issues with persisting histogram height * [Discover] Add tests for histogram height persistence * [Discover] Show reset chart height button only when the layout is resizable * [Discover] Update reset chart height button to read 'Reset to default height' --- .../components/chart/discover_chart.test.tsx | 1 + .../main/components/chart/discover_chart.tsx | 13 +- .../components/chart/use_chart_panels.test.ts | 52 ++++- .../main/components/chart/use_chart_panels.ts | 36 +++- .../layout/discover_main_content.test.tsx | 190 +++++++++++++----- .../layout/discover_main_content.tsx | 38 +++- .../layout/discover_panels.test.tsx | 3 +- .../components/layout/discover_panels.tsx | 9 +- .../layout/discover_panels_resizable.test.tsx | 14 +- .../layout/discover_panels_resizable.tsx | 15 +- 10 files changed, 290 insertions(+), 81 deletions(-) diff --git a/src/plugins/discover/public/application/main/components/chart/discover_chart.test.tsx b/src/plugins/discover/public/application/main/components/chart/discover_chart.test.tsx index b55f0fe714853..155d650583899 100644 --- a/src/plugins/discover/public/application/main/components/chart/discover_chart.test.tsx +++ b/src/plugins/discover/public/application/main/components/chart/discover_chart.test.tsx @@ -114,6 +114,7 @@ async function mountComponent(isTimeBased: boolean = false) { viewMode: VIEW_MODE.DOCUMENT_LEVEL, setDiscoverViewMode: jest.fn(), isTimeBased, + onResetChartHeight: jest.fn(), }; let instance: ReactWrapper = {} as ReactWrapper; diff --git a/src/plugins/discover/public/application/main/components/chart/discover_chart.tsx b/src/plugins/discover/public/application/main/components/chart/discover_chart.tsx index 4bc60e904bb84..4912022e08fdd 100644 --- a/src/plugins/discover/public/application/main/components/chart/discover_chart.tsx +++ b/src/plugins/discover/public/application/main/components/chart/discover_chart.tsx @@ -44,6 +44,7 @@ export function DiscoverChart({ interval, isTimeBased, appendHistogram, + onResetChartHeight, }: { className?: string; resetSavedSearch: () => void; @@ -56,6 +57,7 @@ export function DiscoverChart({ hideChart?: boolean; interval?: string; appendHistogram?: ReactElement; + onResetChartHeight?: () => void; }) { const { data, storage } = useDiscoverServices(); const [showChartOptionsPopover, setShowChartOptionsPopover] = useState(false); @@ -113,13 +115,14 @@ export function DiscoverChart({ }, [data] ); - const panels = useChartPanels( + const panels = useChartPanels({ toggleHideChart, - (newInterval) => stateContainer.setAppState({ interval: newInterval }), - () => setShowChartOptionsPopover(false), + onChangeInterval: (newInterval) => stateContainer.setAppState({ interval: newInterval }), + closePopover: () => setShowChartOptionsPopover(false), + onResetChartHeight, hideChart, - interval - ); + interval, + }); return ( { test('useChartsPanel when hideChart is true', async () => { const { result } = renderHook(() => { - return useChartPanels(jest.fn(), jest.fn(), jest.fn(), true, 'auto'); + return useChartPanels({ + toggleHideChart: jest.fn(), + onChangeInterval: jest.fn(), + closePopover: jest.fn(), + onResetChartHeight: jest.fn(), + hideChart: true, + interval: 'auto', + }); }); const panels: EuiContextMenuPanelDescriptor[] = result.current; const panel0: EuiContextMenuPanelDescriptor = result.current[0]; expect(panels.length).toBe(1); + expect(panel0!.items).toHaveLength(1); expect(panel0!.items![0].icon).toBe('eye'); }); test('useChartsPanel when hideChart is false', async () => { const { result } = renderHook(() => { - return useChartPanels(jest.fn(), jest.fn(), jest.fn(), false, 'auto'); + return useChartPanels({ + toggleHideChart: jest.fn(), + onChangeInterval: jest.fn(), + closePopover: jest.fn(), + onResetChartHeight: jest.fn(), + hideChart: false, + interval: 'auto', + }); }); const panels: EuiContextMenuPanelDescriptor[] = result.current; const panel0: EuiContextMenuPanelDescriptor = result.current[0]; expect(panels.length).toBe(2); + expect(panel0!.items).toHaveLength(3); expect(panel0!.items![0].icon).toBe('eyeClosed'); + expect(panel0!.items![1].icon).toBe('refresh'); + }); + test('should not show reset chart height when onResetChartHeight is undefined', async () => { + const { result } = renderHook(() => { + return useChartPanels({ + toggleHideChart: jest.fn(), + onChangeInterval: jest.fn(), + closePopover: jest.fn(), + hideChart: false, + interval: 'auto', + }); + }); + const panel0: EuiContextMenuPanelDescriptor = result.current[0]; + expect(panel0!.items).toHaveLength(2); + expect(panel0!.items![0].icon).toBe('eyeClosed'); + }); + test('onResetChartHeight is called when the reset chart height button is clicked', async () => { + const onResetChartHeight = jest.fn(); + const { result } = renderHook(() => { + return useChartPanels({ + toggleHideChart: jest.fn(), + onChangeInterval: jest.fn(), + closePopover: jest.fn(), + onResetChartHeight, + hideChart: false, + interval: 'auto', + }); + }); + const panel0: EuiContextMenuPanelDescriptor = result.current[0]; + const resetChartHeightButton = panel0!.items![1]; + (resetChartHeightButton.onClick as Function)(); + expect(onResetChartHeight).toBeCalled(); }); }); diff --git a/src/plugins/discover/public/application/main/components/chart/use_chart_panels.ts b/src/plugins/discover/public/application/main/components/chart/use_chart_panels.ts index bbd670d217e58..f01c72aaee997 100644 --- a/src/plugins/discover/public/application/main/components/chart/use_chart_panels.ts +++ b/src/plugins/discover/public/application/main/components/chart/use_chart_panels.ts @@ -12,13 +12,21 @@ import type { } from '@elastic/eui'; import { search } from '@kbn/data-plugin/public'; -export function useChartPanels( - toggleHideChart: () => void, - onChangeInterval: (value: string) => void, - closePopover: () => void, - hideChart?: boolean, - interval?: string -) { +export function useChartPanels({ + toggleHideChart, + onChangeInterval, + closePopover, + onResetChartHeight, + hideChart, + interval, +}: { + toggleHideChart: () => void; + onChangeInterval: (value: string) => void; + closePopover: () => void; + onResetChartHeight?: () => void; + hideChart?: boolean; + interval?: string; +}) { const selectedOptionIdx = search.aggs.intervalOptions.findIndex((opt) => opt.val === interval); const intervalDisplay = selectedOptionIdx > -1 @@ -43,6 +51,20 @@ export function useChartPanels( }, ]; if (!hideChart) { + if (onResetChartHeight) { + mainPanelItems.push({ + name: i18n.translate('discover.resetChartHeight', { + defaultMessage: 'Reset to default height', + }), + icon: 'refresh', + onClick: () => { + onResetChartHeight(); + closePopover(); + }, + 'data-test-subj': 'discoverChartResetHeight', + }); + } + mainPanelItems.push({ name: i18n.translate('discover.timeIntervalWithValue', { defaultMessage: 'Time interval: {timeInterval}', diff --git a/src/plugins/discover/public/application/main/components/layout/discover_main_content.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_main_content.test.tsx index 6b499aa62c430..ae433ee8ba38e 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_main_content.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_main_content.test.tsx @@ -26,7 +26,11 @@ import { FetchStatus } from '../../../types'; import { Chart } from '../chart/point_series'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { buildDataTableRecord } from '../../../../utils/build_data_record'; -import { DiscoverMainContent, DiscoverMainContentProps } from './discover_main_content'; +import { + DiscoverMainContent, + DiscoverMainContentProps, + HISTOGRAM_HEIGHT_KEY, +} from './discover_main_content'; import { VIEW_MODE } from '@kbn/saved-search-plugin/public'; import { DiscoverPanels, DISCOVER_PANELS_MODE } from './discover_panels'; import { euiThemeVars } from '@kbn/ui-theme'; @@ -36,21 +40,29 @@ import { setTimeout } from 'timers/promises'; import { DiscoverChart } from '../chart'; import { ReactWrapper } from 'enzyme'; import { DocumentViewModeToggle } from '../../../../components/view_mode_toggle'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; +import { LocalStorageMock } from '../../../../__mocks__/local_storage_mock'; const mountComponent = async ({ isPlainRecord = false, hideChart = false, isTimeBased = true, + storage, }: { isPlainRecord?: boolean; hideChart?: boolean; isTimeBased?: boolean; + storage?: Storage; } = {}) => { - const services = discoverServiceMock; + let services = discoverServiceMock; services.data.query.timefilter.timefilter.getAbsoluteTime = () => { return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; }; + if (storage) { + services = { ...services, storage }; + } + const main$ = new BehaviorSubject({ fetchStatus: FetchStatus.COMPLETE, recordRawType: isPlainRecord ? RecordRawType.PLAIN : RecordRawType.DOCUMENT, @@ -188,67 +200,145 @@ describe('Discover main content component', () => { window.innerWidth = windowWidth; }); - it('should set the panels mode to DISCOVER_PANELS_MODE.RESIZABLE when viewing on medium screens and above', async () => { - const component = await mountComponent(); - setWindowWidth(component, euiThemeVars.euiBreakpoints.m); - expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.RESIZABLE); - }); + describe('DISCOVER_PANELS_MODE', () => { + it('should set the panels mode to DISCOVER_PANELS_MODE.RESIZABLE when viewing on medium screens and above', async () => { + const component = await mountComponent(); + setWindowWidth(component, euiThemeVars.euiBreakpoints.m); + expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.RESIZABLE); + }); - it('should set the panels mode to DISCOVER_PANELS_MODE.FIXED when viewing on small screens and below', async () => { - const component = await mountComponent(); - setWindowWidth(component, euiThemeVars.euiBreakpoints.s); - expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.FIXED); - }); + it('should set the panels mode to DISCOVER_PANELS_MODE.FIXED when viewing on small screens and below', async () => { + const component = await mountComponent(); + setWindowWidth(component, euiThemeVars.euiBreakpoints.s); + expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.FIXED); + }); - it('should set the panels mode to DISCOVER_PANELS_MODE.FIXED if hideChart is true', async () => { - const component = await mountComponent({ hideChart: true }); - expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.FIXED); - }); + it('should set the panels mode to DISCOVER_PANELS_MODE.FIXED if hideChart is true', async () => { + const component = await mountComponent({ hideChart: true }); + expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.FIXED); + }); - it('should set the panels mode to DISCOVER_PANELS_MODE.FIXED if isTimeBased is false', async () => { - const component = await mountComponent({ isTimeBased: false }); - expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.FIXED); - }); + it('should set the panels mode to DISCOVER_PANELS_MODE.FIXED if isTimeBased is false', async () => { + const component = await mountComponent({ isTimeBased: false }); + expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.FIXED); + }); - it('should set the panels mode to DISCOVER_PANELS_MODE.SINGLE if isPlainRecord is true', async () => { - const component = await mountComponent({ isPlainRecord: true }); - expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.SINGLE); - }); + it('should set the panels mode to DISCOVER_PANELS_MODE.SINGLE if isPlainRecord is true', async () => { + const component = await mountComponent({ isPlainRecord: true }); + expect(component.find(DiscoverPanels).prop('mode')).toBe(DISCOVER_PANELS_MODE.SINGLE); + }); - it('should set a fixed height for DiscoverChart when panels mode is DISCOVER_PANELS_MODE.FIXED and hideChart is false', async () => { - const component = await mountComponent(); - setWindowWidth(component, euiThemeVars.euiBreakpoints.s); - const expectedHeight = component.find(DiscoverPanels).prop('initialTopPanelHeight'); - expect(component.find(DiscoverChart).childAt(0).getDOMNode()).toHaveStyle({ - height: `${expectedHeight}px`, + it('should set a fixed height for DiscoverChart when panels mode is DISCOVER_PANELS_MODE.FIXED and hideChart is false', async () => { + const component = await mountComponent(); + setWindowWidth(component, euiThemeVars.euiBreakpoints.s); + const expectedHeight = component.find(DiscoverPanels).prop('topPanelHeight'); + expect(component.find(DiscoverChart).childAt(0).getDOMNode()).toHaveStyle({ + height: `${expectedHeight}px`, + }); }); - }); - it('should not set a fixed height for DiscoverChart when panels mode is DISCOVER_PANELS_MODE.FIXED and hideChart is true', async () => { - const component = await mountComponent({ hideChart: true }); - setWindowWidth(component, euiThemeVars.euiBreakpoints.s); - const expectedHeight = component.find(DiscoverPanels).prop('initialTopPanelHeight'); - expect(component.find(DiscoverChart).childAt(0).getDOMNode()).not.toHaveStyle({ - height: `${expectedHeight}px`, + it('should not set a fixed height for DiscoverChart when panels mode is DISCOVER_PANELS_MODE.FIXED and hideChart is true', async () => { + const component = await mountComponent({ hideChart: true }); + setWindowWidth(component, euiThemeVars.euiBreakpoints.s); + const expectedHeight = component.find(DiscoverPanels).prop('topPanelHeight'); + expect(component.find(DiscoverChart).childAt(0).getDOMNode()).not.toHaveStyle({ + height: `${expectedHeight}px`, + }); }); - }); - it('should not set a fixed height for DiscoverChart when panels mode is DISCOVER_PANELS_MODE.FIXED and isTimeBased is false', async () => { - const component = await mountComponent({ isTimeBased: false }); - setWindowWidth(component, euiThemeVars.euiBreakpoints.s); - const expectedHeight = component.find(DiscoverPanels).prop('initialTopPanelHeight'); - expect(component.find(DiscoverChart).childAt(0).getDOMNode()).not.toHaveStyle({ - height: `${expectedHeight}px`, + it('should not set a fixed height for DiscoverChart when panels mode is DISCOVER_PANELS_MODE.FIXED and isTimeBased is false', async () => { + const component = await mountComponent({ isTimeBased: false }); + setWindowWidth(component, euiThemeVars.euiBreakpoints.s); + const expectedHeight = component.find(DiscoverPanels).prop('topPanelHeight'); + expect(component.find(DiscoverChart).childAt(0).getDOMNode()).not.toHaveStyle({ + height: `${expectedHeight}px`, + }); + }); + + it('should pass undefined for onResetChartHeight to DiscoverChart when panels mode is DISCOVER_PANELS_MODE.FIXED', async () => { + const component = await mountComponent(); + expect(component.find(DiscoverChart).prop('onResetChartHeight')).toBeDefined(); + setWindowWidth(component, euiThemeVars.euiBreakpoints.s); + expect(component.find(DiscoverChart).prop('onResetChartHeight')).toBeUndefined(); }); }); - it('should show DocumentViewModeToggle when isPlainRecord is false', async () => { - const component = await mountComponent(); - expect(component.find(DocumentViewModeToggle).exists()).toBe(true); + describe('DocumentViewModeToggle', () => { + it('should show DocumentViewModeToggle when isPlainRecord is false', async () => { + const component = await mountComponent(); + expect(component.find(DocumentViewModeToggle).exists()).toBe(true); + }); + + it('should not show DocumentViewModeToggle when isPlainRecord is true', async () => { + const component = await mountComponent({ isPlainRecord: true }); + expect(component.find(DocumentViewModeToggle).exists()).toBe(false); + }); }); - it('should not show DocumentViewModeToggle when isPlainRecord is true', async () => { - const component = await mountComponent({ isPlainRecord: true }); - expect(component.find(DocumentViewModeToggle).exists()).toBe(false); + describe('topPanelHeight persistence', () => { + it('should try to get the initial topPanelHeight for DiscoverPanels from storage', async () => { + const storage = new LocalStorageMock({}) as unknown as Storage; + const originalGet = storage.get; + storage.get = jest.fn().mockImplementation(originalGet); + await mountComponent({ storage }); + expect(storage.get).toHaveBeenCalledWith(HISTOGRAM_HEIGHT_KEY); + }); + + it('should pass a default topPanelHeight to DiscoverPanels if no value is found in storage', async () => { + const storage = new LocalStorageMock({}) as unknown as Storage; + const originalGet = storage.get; + storage.get = jest.fn().mockImplementation(originalGet); + const component = await mountComponent({ storage }); + expect(storage.get).toHaveBeenCalledWith(HISTOGRAM_HEIGHT_KEY); + expect(storage.get).toHaveReturnedWith(null); + expect(component.find(DiscoverPanels).prop('topPanelHeight')).toBeGreaterThan(0); + }); + + it('should pass the stored topPanelHeight to DiscoverPanels if a value is found in storage', async () => { + const storage = new LocalStorageMock({}) as unknown as Storage; + const topPanelHeight = 123; + storage.get = jest.fn().mockImplementation(() => topPanelHeight); + const component = await mountComponent({ storage }); + expect(storage.get).toHaveBeenCalledWith(HISTOGRAM_HEIGHT_KEY); + expect(storage.get).toHaveReturnedWith(topPanelHeight); + expect(component.find(DiscoverPanels).prop('topPanelHeight')).toBe(topPanelHeight); + }); + + it('should update the topPanelHeight in storage and pass the new value to DiscoverPanels when the topPanelHeight changes', async () => { + const storage = new LocalStorageMock({}) as unknown as Storage; + const originalSet = storage.set; + storage.set = jest.fn().mockImplementation(originalSet); + const component = await mountComponent({ storage }); + const newTopPanelHeight = 123; + expect(component.find(DiscoverPanels).prop('topPanelHeight')).not.toBe(newTopPanelHeight); + act(() => { + component.find(DiscoverPanels).prop('onTopPanelHeightChange')(newTopPanelHeight); + }); + component.update(); + expect(storage.set).toHaveBeenCalledWith(HISTOGRAM_HEIGHT_KEY, newTopPanelHeight); + expect(component.find(DiscoverPanels).prop('topPanelHeight')).toBe(newTopPanelHeight); + }); + + it('should reset the topPanelHeight to the default when onResetChartHeight is called on DiscoverChart', async () => { + const storage = new LocalStorageMock({}) as unknown as Storage; + const originalSet = storage.set; + storage.set = jest.fn().mockImplementation(originalSet); + const component = await mountComponent({ storage }); + const defaultTopPanelHeight = component.find(DiscoverPanels).prop('topPanelHeight'); + const newTopPanelHeight = 123; + expect(component.find(DiscoverPanels).prop('topPanelHeight')).not.toBe(newTopPanelHeight); + act(() => { + component.find(DiscoverPanels).prop('onTopPanelHeightChange')(newTopPanelHeight); + }); + component.update(); + expect(storage.set).toHaveBeenCalledWith(HISTOGRAM_HEIGHT_KEY, newTopPanelHeight); + expect(component.find(DiscoverPanels).prop('topPanelHeight')).toBe(newTopPanelHeight); + act(() => { + component.find(DiscoverChart).prop('onResetChartHeight')!(); + }); + component.update(); + expect(storage.set).toHaveBeenCalledWith(HISTOGRAM_HEIGHT_KEY, defaultTopPanelHeight); + expect(component.find(DiscoverPanels).prop('topPanelHeight')).toBe(defaultTopPanelHeight); + }); }); }); diff --git a/src/plugins/discover/public/application/main/components/layout/discover_main_content.tsx b/src/plugins/discover/public/application/main/components/layout/discover_main_content.tsx index 747ccc9512a5f..68d91c9123a6d 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_main_content.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_main_content.tsx @@ -15,7 +15,7 @@ import { useIsWithinBreakpoints, } from '@elastic/eui'; import { SavedSearch } from '@kbn/saved-search-plugin/public'; -import React, { RefObject, useCallback, useMemo } from 'react'; +import React, { RefObject, useCallback, useMemo, useState } from 'react'; import { DataView } from '@kbn/data-views-plugin/common'; import { METRIC_TYPE } from '@kbn/analytics'; import { createHtmlPortalNode, InPortal, OutPortal } from 'react-reverse-portal'; @@ -35,6 +35,8 @@ import { DiscoverPanels, DISCOVER_PANELS_MODE } from './discover_panels'; const DiscoverChartMemoized = React.memo(DiscoverChart); const FieldStatisticsTableMemoized = React.memo(FieldStatisticsTable); +export const HISTOGRAM_HEIGHT_KEY = 'discover:histogramHeight'; + export interface DiscoverMainContentProps { isPlainRecord: boolean; dataView: DataView; @@ -74,7 +76,7 @@ export const DiscoverMainContent = ({ columns, resizeRef, }: DiscoverMainContentProps) => { - const { trackUiMetric } = useDiscoverServices(); + const { trackUiMetric, storage } = useDiscoverServices(); const setDiscoverViewMode = useCallback( (mode: VIEW_MODE) => { @@ -104,14 +106,36 @@ export const DiscoverMainContent = ({ const hideChart = state.hideChart || !isTimeBased; const showFixedPanels = useIsWithinBreakpoints(['xs', 's']) || isPlainRecord || hideChart; const { euiTheme } = useEuiTheme(); - const topPanelHeight = euiTheme.base * 12; + const defaultTopPanelHeight = euiTheme.base * 12; const minTopPanelHeight = euiTheme.base * 8; const minMainPanelHeight = euiTheme.base * 10; + const [topPanelHeight, setTopPanelHeight] = useState( + Number(storage.get(HISTOGRAM_HEIGHT_KEY)) || defaultTopPanelHeight + ); + + const storeTopPanelHeight = useCallback( + (newTopPanelHeight: number) => { + storage.set(HISTOGRAM_HEIGHT_KEY, newTopPanelHeight); + setTopPanelHeight(newTopPanelHeight); + }, + [storage] + ); + + const resetTopPanelHeight = useCallback( + () => storeTopPanelHeight(defaultTopPanelHeight), + [storeTopPanelHeight, defaultTopPanelHeight] + ); + + const onTopPanelHeightChange = useCallback( + (newTopPanelHeight: number) => storeTopPanelHeight(newTopPanelHeight), + [storeTopPanelHeight] + ); + const chartClassName = showFixedPanels && !hideChart ? css` - height: ${topPanelHeight}px; + height: ${defaultTopPanelHeight}px; ` : 'eui-fullHeight'; @@ -136,6 +160,9 @@ export const DiscoverMainContent = ({ interval={state.interval} isTimeBased={isTimeBased} appendHistogram={showFixedPanels ? : } + onResetChartHeight={ + panelsMode === DISCOVER_PANELS_MODE.RESIZABLE ? resetTopPanelHeight : undefined + } /> @@ -189,11 +216,12 @@ export const DiscoverMainContent = ({ className="dscPageContent__inner" mode={panelsMode} resizeRef={resizeRef} - initialTopPanelHeight={topPanelHeight} + topPanelHeight={topPanelHeight} minTopPanelHeight={minTopPanelHeight} minMainPanelHeight={minMainPanelHeight} topPanel={} mainPanel={} + onTopPanelHeightChange={onTopPanelHeightChange} /> ); diff --git a/src/plugins/discover/public/application/main/components/layout/discover_panels.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_panels.test.tsx index 60ba0038f1194..c136675494fb3 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_panels.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_panels.test.tsx @@ -34,11 +34,12 @@ describe('Discover panels component', () => { ); }; diff --git a/src/plugins/discover/public/application/main/components/layout/discover_panels.tsx b/src/plugins/discover/public/application/main/components/layout/discover_panels.tsx index 57ea08ee92c8b..b79d9fb96aaeb 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_panels.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_panels.tsx @@ -20,11 +20,12 @@ export interface DiscoverPanelsProps { className?: string; mode: DISCOVER_PANELS_MODE; resizeRef: RefObject; - initialTopPanelHeight: number; + topPanelHeight: number; minTopPanelHeight: number; minMainPanelHeight: number; topPanel: ReactElement; mainPanel: ReactElement; + onTopPanelHeightChange: (height: number) => void; } const fixedModes = [DISCOVER_PANELS_MODE.SINGLE, DISCOVER_PANELS_MODE.FIXED]; @@ -33,11 +34,12 @@ export const DiscoverPanels = ({ className, mode, resizeRef, - initialTopPanelHeight, + topPanelHeight, minTopPanelHeight, minMainPanelHeight, topPanel, mainPanel, + onTopPanelHeightChange, }: DiscoverPanelsProps) => { const panelsProps = { className, topPanel, mainPanel }; @@ -46,9 +48,10 @@ export const DiscoverPanels = ({ ) : ( ); diff --git a/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.test.tsx index 16c50a94b4656..c919504091c21 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.test.tsx @@ -33,6 +33,7 @@ describe('Discover panels resizable', () => { topPanel = <>, mainPanel = <>, attachTo, + onTopPanelHeightChange = jest.fn(), }: { className?: string; resizeRef?: RefObject; @@ -42,16 +43,18 @@ describe('Discover panels resizable', () => { topPanel?: ReactElement; mainPanel?: ReactElement; attachTo?: HTMLElement; + onTopPanelHeightChange?: (height: number) => void; }) => { return mount( , attachTo ? { attachTo } : undefined ); @@ -95,7 +98,10 @@ describe('Discover panels resizable', () => { it('should set the correct heights of both panels when the panels are resized', () => { const initialTopPanelHeight = 200; - const component = mountComponent({ initialTopPanelHeight }); + const onTopPanelHeightChange = jest.fn((topPanelHeight) => { + component.setProps({ topPanelHeight }).update(); + }); + const component = mountComponent({ initialTopPanelHeight, onTopPanelHeightChange }); expectCorrectPanelSizes(component, containerHeight, initialTopPanelHeight); const newTopPanelSize = 30; const onPanelSizeChange = component @@ -106,7 +112,9 @@ describe('Discover panels resizable', () => { onPanelSizeChange({ [topPanelId]: newTopPanelSize }); }); forceRender(component); - expectCorrectPanelSizes(component, containerHeight, containerHeight * (newTopPanelSize / 100)); + const newTopPanelHeight = (newTopPanelSize / 100) * containerHeight; + expect(onTopPanelHeightChange).toHaveBeenCalledWith(newTopPanelHeight); + expectCorrectPanelSizes(component, containerHeight, newTopPanelHeight); }); it('should maintain the height of the top panel and resize the main panel when the container height changes', () => { diff --git a/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.tsx b/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.tsx index 88a92b4380b76..b65da1eb0bf68 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_panels_resizable.tsx @@ -19,23 +19,24 @@ const pixelsToPercent = (containerHeight: number, pixels: number) => export const DiscoverPanelsResizable = ({ className, resizeRef, - initialTopPanelHeight, + topPanelHeight, minTopPanelHeight, minMainPanelHeight, topPanel, mainPanel, + onTopPanelHeightChange, }: { className?: string; resizeRef: RefObject; - initialTopPanelHeight: number; + topPanelHeight: number; minTopPanelHeight: number; minMainPanelHeight: number; topPanel: ReactElement; mainPanel: ReactElement; + onTopPanelHeightChange: (height: number) => void; }) => { const topPanelId = useGeneratedHtmlId({ prefix: 'topPanel' }); const { height: containerHeight } = useResizeObserver(resizeRef.current); - const [topPanelHeight, setTopPanelHeight] = useState(initialTopPanelHeight); const [panelSizes, setPanelSizes] = useState({ topPanelSize: 0, mainPanelSize: 0 }); // EuiResizableContainer doesn't work properly when used with react-reverse-portal and @@ -69,9 +70,13 @@ export const DiscoverPanelsResizable = ({ // the effect below to update the panel sizes. const onPanelSizeChange = useCallback( ({ [topPanelId]: topPanelSize }: { [key: string]: number }) => { - setTopPanelHeight(percentToPixels(containerHeight, topPanelSize)); + const newTopPanelHeight = percentToPixels(containerHeight, topPanelSize); + + if (newTopPanelHeight !== topPanelHeight) { + onTopPanelHeightChange(newTopPanelHeight); + } }, - [containerHeight, topPanelId] + [containerHeight, onTopPanelHeightChange, topPanelHeight, topPanelId] ); // This effect will update the panel sizes based on the top panel height whenever From 9a77d2408cd6741d01b6a56736c7c2688c93286f Mon Sep 17 00:00:00 2001 From: Karl Godard Date: Tue, 20 Sep 2022 19:06:09 -0700 Subject: [PATCH 30/55] =?UTF-8?q?[Terminal=20Output]=20tty=20toggle=20now?= =?UTF-8?q?=20shows=20number=20of=20bytes=20in=20tooltip,=20if=20no=20outp?= =?UTF-8?q?ut=20we=20disa=E2=80=A6=20(#141174)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * tty toggle now shows number of bytes in tooltip, if no output we disable button (instead of hide) * fixed tests Co-authored-by: Karl Godard --- package.json | 3 +- packages/kbn-test/jest-preset.js | 2 +- renovate.json | 9 ++++ .../components/session_view/index.test.tsx | 6 ++- .../public/components/session_view/index.tsx | 51 ++++++++++--------- .../public/components/tty_player/styles.ts | 3 +- yarn.lock | 15 ++++-- 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 1ee38e61ba5af..c138d74d8f0a8 100644 --- a/package.json +++ b/package.json @@ -416,6 +416,7 @@ "@turf/distance": "6.0.1", "@turf/helpers": "6.0.1", "@turf/length": "^6.0.2", + "@types/byte-size": "^8.1.0", "JSONStream": "1.3.5", "abort-controller": "^3.0.0", "antlr4ts": "^0.5.0-alpha.3", @@ -424,6 +425,7 @@ "base64-js": "^1.3.1", "bitmap-sdf": "^1.0.3", "brace": "0.11.1", + "byte-size": "^8.1.0", "canvg": "^3.0.9", "cbor-x": "^1.3.3", "chalk": "^4.1.0", @@ -635,7 +637,6 @@ "whatwg-fetch": "^3.0.0", "xml2js": "^0.4.22", "xterm": "^4.18.0", - "xterm-addon-fit": "^0.5.0", "yauzl": "^2.10.0", "yazl": "^2.5.1" }, diff --git a/packages/kbn-test/jest-preset.js b/packages/kbn-test/jest-preset.js index 35cef7b672a3d..3cb0ce86602cd 100644 --- a/packages/kbn-test/jest-preset.js +++ b/packages/kbn-test/jest-preset.js @@ -127,7 +127,7 @@ module.exports = { transformIgnorePatterns: [ // ignore all node_modules except monaco-editor and react-monaco-editor which requires babel transforms to handle dynamic import() // since ESM modules are not natively supported in Jest yet (https://github.com/facebook/jest/issues/4842) - '[/\\\\]node_modules(?![\\/\\\\](monaco-editor|react-monaco-editor|d3-interpolate|d3-color))[/\\\\].+\\.js$', + '[/\\\\]node_modules(?![\\/\\\\](byte-size|monaco-editor|react-monaco-editor|d3-interpolate|d3-color))[/\\\\].+\\.js$', 'packages/kbn-pm/dist/index.js', ], diff --git a/renovate.json b/renovate.json index 508cdcc684fc2..6eed31366c409 100644 --- a/renovate.json +++ b/renovate.json @@ -216,6 +216,15 @@ "labels": ["release_note:skip", "backport:skip"], "enabled": true, "prCreation": "immediate" + }, + { + "groupName": "TTY Output", + "matchPackageNames": ["xterm", "byte-size", "@types/byte-size"], + "reviewers": ["team:awp-viz"], + "matchBaseBranches": ["main"], + "labels": ["Team: AWP: Visualization", "release_note:skip", "backport:skip"], + "enabled": true, + "prCreation": "immediate" } ] } diff --git a/x-pack/plugins/session_view/public/components/session_view/index.test.tsx b/x-pack/plugins/session_view/public/components/session_view/index.test.tsx index ccda24a88c559..e4650ca2eb4f1 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.test.tsx @@ -189,7 +189,7 @@ describe('SessionView component', () => { }); }); - it('should NOT show tty player button, if session has no output', async () => { + it('should show tty player button as disabled, if session has no output', async () => { mockedApi.mockImplementation(async (options) => { // for some reason the typescript interface for options says its an object with a field called path. // in reality options is a string (which equals the path...) @@ -207,7 +207,9 @@ describe('SessionView component', () => { render(); await waitFor(() => { - expect(renderResult.queryByTestId('sessionView:TTYPlayerToggle')).toBeFalsy(); + expect(renderResult.queryByTestId('sessionView:TTYPlayerToggle')).toHaveClass( + 'euiButtonIcon-isDisabled' + ); }); }); }); diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx index 07626d090bd2b..32cc5dffdea5d 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx @@ -18,6 +18,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import useLocalStorage from 'react-use/lib/useLocalStorage'; +import byteSize from 'byte-size'; import { SectionLoading } from '../../shared_imports'; import { ProcessTree } from '../process_tree'; import { @@ -141,6 +142,11 @@ export const SessionView = ({ const { data: totalTTYOutputBytes, refetch: refetchTotalTTYOutput } = useFetchGetTotalIOBytes(sessionEntityId); const hasTTYOutput = !!totalTTYOutputBytes?.total; + const bytesOfOutput = useMemo(() => { + const { unit, value } = byteSize(totalTTYOutputBytes?.total || 0); + + return { unit, value }; + }, [totalTTYOutputBytes?.total]); const handleRefresh = useCallback(() => { refetch({ refetchPage: (_page, index, allPages) => allPages.length - 1 === index }); @@ -268,31 +274,30 @@ export const SessionView = ({ /> - {hasTTYOutput && ( - - + + {bytesOfOutput.value} {bytesOfOutput.unit} - } - > - - - - )} + + } + > + + + { }; const header: CSSObject = { + display: show ? 'block' : 'none', backgroundColor: `${euiVars.euiFormBackgroundDisabledColor}`, padding: `${size.m} ${size.base}`, }; @@ -73,7 +74,7 @@ export const useStyles = (tty?: Teletype, show?: boolean) => { const scrollPane: CSSObject = { position: 'relative', transform: `translateY(${show ? 0 : '100%'})`, - transition: 'transform .2s', + transition: 'transform .2s ease-in-out', width: '100%', height: 'calc(100% - 112px)', overflow: 'auto', diff --git a/yarn.lock b/yarn.lock index 012d925b7557e..4e681bb73808f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6044,6 +6044,11 @@ resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw== +"@types/byte-size@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/byte-size/-/byte-size-8.1.0.tgz#013a3995d1ff2d85ad27da0801029f13328bd91b" + integrity sha512-LCIlZh8vyx+I2fgRycE1D34c33QDppYY6quBYYoaOpQ1nGhJ/avSP2VlrAefVotjJxgSk6WkKo0rTcCJwGG7vA== + "@types/cacheable-request@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" @@ -10713,6 +10718,11 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +byte-size@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.0.tgz#6353d0bc14ab7a69abcefbf11f8db0145a862cb5" + integrity sha512-FkgMTAg44I0JtEaUAvuZTtU2a2YDmBRbQxdsQNSMtLCjhG0hMcF5b1IMN9UjSCJaU4nvlj/GER7B9sI4nKdCgA== + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -28522,11 +28532,6 @@ xpath@0.0.32: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -xterm-addon-fit@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz#2d51b983b786a97dcd6cde805e700c7f913bc596" - integrity sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ== - xterm@^4.18.0: version "4.18.0" resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.18.0.tgz#a1f6ab2c330c3918fb094ae5f4c2562987398ea1" From d7872286cbeb5280656bb7e47da2fb400db29e74 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 20 Sep 2022 22:38:58 -0600 Subject: [PATCH 31/55] [api-docs] Daily api_docs build (#141181) --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.devdocs.json | 50 +- api_docs/apm.mdx | 4 +- 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_experiments.devdocs.json | 370 ++++++++++++++ api_docs/cloud_experiments.mdx | 33 ++ api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/core.devdocs.json | 481 +++++++++++++++++- api_docs/core.mdx | 4 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.devdocs.json | 4 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 7 +- api_docs/deprecations_by_plugin.mdx | 9 +- api_docs/deprecations_by_team.mdx | 7 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.devdocs.json | 25 +- api_docs/discover.mdx | 4 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.devdocs.json | 6 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.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.devdocs.json | 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/fleet.devdocs.json | 248 ++++++++- api_docs/fleet.mdx | 4 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.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_alerts.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_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.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_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_table_list.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_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_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 +- .../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 +- .../kbn_core_injected_metadata_browser.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_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 +- ...bn_core_notifications_browser.devdocs.json | 4 +- 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_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- ...ore_saved_objects_api_browser.devdocs.json | 206 ++++++++ .../kbn_core_saved_objects_api_browser.mdx | 4 +- ...core_saved_objects_api_server.devdocs.json | 387 ++++++++++++++ .../kbn_core_saved_objects_api_server.mdx | 4 +- ...d_objects_api_server_internal.devdocs.json | 56 ++ ...core_saved_objects_api_server_internal.mdx | 4 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...saved_objects_server_internal.devdocs.json | 50 ++ ...kbn_core_saved_objects_server_internal.mdx | 4 +- .../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_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 +- .../kbn_core_usage_data_server.devdocs.json | 98 ++++ api_docs/kbn_core_usage_data_server.mdx | 4 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- ..._core_usage_data_server_mocks.devdocs.json | 2 + api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.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_ebt_tools.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.devdocs.json | 463 +++++++++++++++++ api_docs/kbn_es_types.mdx | 33 ++ api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_get_repo_files.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.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_import_resolver.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.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_ml_agg_utils.devdocs.json | 94 ++++ api_docs/kbn_ml_agg_utils.mdx | 4 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.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_react_field.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.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_shared_svg.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- .../kbn_shared_ux_card_no_data.devdocs.json | 6 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_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_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_some_dev_log.mdx | 2 +- api_docs/kbn_sort_package_json.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_tooling_log.mdx | 2 +- api_docs/kbn_type_summarizer.mdx | 2 +- api_docs/kbn_type_summarizer_core.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_theme.devdocs.json | 8 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.devdocs.json | 6 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.devdocs.json | 115 ++++- api_docs/lens.mdx | 4 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.devdocs.json | 4 + 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/observability.devdocs.json | 213 +++++++- api_docs/observability.mdx | 4 +- api_docs/osquery.devdocs.json | 115 ++++- api_docs/osquery.mdx | 4 +- api_docs/plugin_directory.mdx | 44 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.devdocs.json | 225 +++++++- api_docs/rule_registry.mdx | 4 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- .../saved_objects_management.devdocs.json | 6 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.devdocs.json | 18 +- api_docs/security_solution.mdx | 4 +- 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/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.devdocs.json | 154 +++++- api_docs/triggers_actions_ui.mdx | 4 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.devdocs.json | 41 +- api_docs/ui_actions_enhanced.mdx | 4 +- api_docs/unified_field_list.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/visualizations.devdocs.json | 295 +++++++++++ api_docs/visualizations.mdx | 4 +- 425 files changed, 4171 insertions(+), 528 deletions(-) create mode 100644 api_docs/cloud_experiments.devdocs.json create mode 100644 api_docs/cloud_experiments.mdx create mode 100644 api_docs/kbn_es_types.devdocs.json create mode 100644 api_docs/kbn_es_types.mdx diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index dcbf086f39208..bdf14bf19ae84 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: 2022-09-20 +date: 2022-09-21 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 99d010dcd47bb..1dbd552804863 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: 2022-09-20 +date: 2022-09-21 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 fb6b6937fc76b..16ee88902efc4 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: 2022-09-20 +date: 2022-09-21 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 70b1838415a1c..3a59a9f336d06 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index b0e9d5757bffd..1ad2876e6274d 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -196,7 +196,7 @@ "APMPluginSetupDependencies", ") => { config$: ", "Observable", - "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", + "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedServiceMetrics: boolean; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>>; getApmIndices: () => Promise<", "ApmIndicesConfig", @@ -415,7 +415,7 @@ "label": "config", "description": [], "signature": [ - "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", + "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedServiceMetrics: boolean; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }" ], @@ -781,7 +781,7 @@ "label": "APIEndpoint", "description": [], "signature": [ - "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"GET /internal/apm/services/{serviceName}/serviceNodes\" | \"GET /internal/apm/services\" | \"POST /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_rate\" | \"GET /internal/apm/alerts/chart_preview/transaction_duration\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_count\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/operations/spans\" | \"GET /internal/apm/correlations/field_candidates/transactions\" | \"POST /internal/apm/correlations/field_stats/transactions\" | \"GET /internal/apm/correlations/field_value_stats/transactions\" | \"POST /internal/apm/correlations/field_value_pairs/transactions\" | \"POST /internal/apm/correlations/significant_correlations/transactions\" | \"POST /internal/apm/correlations/p_values/transactions\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\" | \"GET /internal/apm/settings/labs\"" + "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"GET /internal/apm/services/{serviceName}/serviceNodes\" | \"GET /internal/apm/services\" | \"POST /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/service_groups/services_count\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_rate\" | \"GET /internal/apm/alerts/chart_preview/transaction_duration\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_count\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/operations/spans\" | \"GET /internal/apm/correlations/field_candidates/transactions\" | \"POST /internal/apm/correlations/field_stats/transactions\" | \"GET /internal/apm/correlations/field_value_stats/transactions\" | \"POST /internal/apm/correlations/field_value_pairs/transactions\" | \"POST /internal/apm/correlations/significant_correlations/transactions\" | \"POST /internal/apm/correlations/p_values/transactions\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\" | \"GET /internal/apm/settings/labs\"" ], "path": "x-pack/plugins/apm/server/routes/apm_routes/get_global_apm_server_route_repository.ts", "deprecated": false, @@ -811,7 +811,7 @@ "label": "APMConfig", "description": [], "signature": [ - "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", + "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedServiceMetrics: boolean; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }" ], @@ -3881,6 +3881,26 @@ }, ", { terms: string[]; }, ", "APMRouteCreateOptions", + ">; \"GET /internal/apm/service_groups/services_count\": ", + "ServerRoute", + "<\"GET /internal/apm/service_groups/services_count\", ", + "TypeC", + "<{ query: ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", { servicesCounts: Record; }, ", + "APMRouteCreateOptions", ">; \"GET /internal/apm/service-group/services\": ", "ServerRoute", "<\"GET /internal/apm/service-group/services\", ", @@ -3932,18 +3952,14 @@ "<\"POST /internal/apm/service-group\", ", "TypeC", "<{ query: ", - "IntersectionC", + "UnionC", "<[", - "TypeC", - "<{ start: ", - "Type", - "; end: ", - "Type", - "; }>, ", "PartialC", "<{ serviceGroupId: ", "StringC", - "; }>]>; body: ", + "; }>, ", + "UndefinedC", + "]>; body: ", "TypeC", "<{ groupName: ", "StringC", @@ -5091,11 +5107,9 @@ "section": "def-server.APMRouteHandlerResources", "text": "APMRouteHandlerResources" }, - ", { charts: { title: string; key: string; yUnit: ", - "YUnit", - "; series: { title: string; key: string; type: ", - "ChartType", - "; color: string; overallValue: number; data: { x: number; y: number | null; }[]; }[]; }[]; }, ", + ", { charts: ", + "FetchAndTransformMetrics", + "[]; }, ", "APMRouteCreateOptions", ">; \"POST /internal/apm/latency/overall_distribution/transactions\": ", "ServerRoute", @@ -5604,7 +5618,7 @@ "description": [], "signature": [ "Observable", - "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", + "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedServiceMetrics: boolean; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>>" ], diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 4e665c7bfea03..936fb386563a2 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; @@ -21,7 +21,7 @@ Contact [APM UI](https://github.com/orgs/elastic/teams/apm-ui) for questions reg | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 38 | 0 | 38 | 52 | +| 38 | 0 | 38 | 51 | ## Client diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index dcb08b6198153..9f93e0cf30bad 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: 2022-09-20 +date: 2022-09-21 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 dce7e1d14c5ca..03ef60650c287 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: 2022-09-20 +date: 2022-09-21 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 46a35412e6ae1..e1070b82be030 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: 2022-09-20 +date: 2022-09-21 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 a6ee546714ecf..9c1f56437d048 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: 2022-09-20 +date: 2022-09-21 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 b62a72791c792..496b2c6c79551 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: 2022-09-20 +date: 2022-09-21 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 d88f07961f1e9..58a63e62dd73a 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_experiments.devdocs.json b/api_docs/cloud_experiments.devdocs.json new file mode 100644 index 0000000000000..0f827e35ec52a --- /dev/null +++ b/api_docs/cloud_experiments.devdocs.json @@ -0,0 +1,370 @@ +{ + "id": "cloudExperiments", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsMetric", + "type": "Interface", + "tags": [], + "label": "CloudExperimentsMetric", + "description": [ + "\nDefinition of the metric to report back to the A/B testing service to measure the conversions.\n" + ], + "signature": [ + { + "pluginId": "cloudExperiments", + "scope": "common", + "docId": "kibCloudExperimentsPluginApi", + "section": "def-common.CloudExperimentsMetric", + "text": "CloudExperimentsMetric" + }, + "" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsMetric.name", + "type": "Uncategorized", + "tags": [], + "label": "name", + "description": [ + "\nThe name of the metric {@link CloudExperimentsMetricNames}" + ], + "signature": [ + "never" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsMetric.meta", + "type": "Uncategorized", + "tags": [], + "label": "meta", + "description": [ + "\nAny optional data to enrich the context of the metric. Or if the conversion is based on a non-numeric value." + ], + "signature": [ + "Data | undefined" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsMetric.value", + "type": "number", + "tags": [], + "label": "value", + "description": [ + "\nThe numeric value of the metric. Bear in mind that they are averaged by the underlying solution.\nTypical values to report here are time-to-action, number of panels in a loaded dashboard, and page load time." + ], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginSetup", + "type": "Interface", + "tags": [], + "label": "CloudExperimentsPluginSetup", + "description": [ + "\nThe contract of the setup lifecycle method.\n" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginSetup.identifyUser", + "type": "Function", + "tags": [ + "deprecated" + ], + "label": "identifyUser", + "description": [ + "\nIdentifies the user in the A/B testing service.\nFor now, we only rely on the user ID. In the future, we may request further details for more targeted experiments." + ], + "signature": [ + "(userId: string, userMetadata?: Record | undefined) => void" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": true, + "trackAdoption": false, + "references": [ + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/public/plugin.tsx" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/server/plugin.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/public/plugin.test.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/public/plugin.test.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/public/plugin.test.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/public/plugin.test.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/server/plugin.test.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/server/plugin.test.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/server/plugin.test.ts" + }, + { + "plugin": "cloud", + "path": "x-pack/plugins/cloud/server/plugin.test.ts" + } + ], + "children": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginSetup.identifyUser.$1", + "type": "string", + "tags": [], + "label": "userId", + "description": [ + "The unique identifier of the user in the experiment." + ], + "signature": [ + "string" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginSetup.identifyUser.$2", + "type": "Object", + "tags": [], + "label": "userMetadata", + "description": [ + "Additional attributes to the user. Take care to ensure these values do not contain PII." + ], + "signature": [ + "Record | undefined" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginStart", + "type": "Interface", + "tags": [], + "label": "CloudExperimentsPluginStart", + "description": [ + "\nThe contract of the start lifecycle method\n" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginStart.getVariation", + "type": "Function", + "tags": [], + "label": "getVariation", + "description": [ + "\nFetch the configuration assigned to variation `configKey`. If nothing is found, fallback to `defaultValue`." + ], + "signature": [ + "(featureFlagName: \"security-solutions.add-integrations-url\", defaultValue: Data) => Promise" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginStart.getVariation.$1", + "type": "string", + "tags": [], + "label": "featureFlagName", + "description": [ + "The name of the key to find the config variation. {@link CloudExperimentsFeatureFlagNames }." + ], + "signature": [ + "\"security-solutions.add-integrations-url\"" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginStart.getVariation.$2", + "type": "Uncategorized", + "tags": [], + "label": "defaultValue", + "description": [ + "The fallback value in case no variation is found." + ], + "signature": [ + "Data" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginStart.reportMetric", + "type": "Function", + "tags": [], + "label": "reportMetric", + "description": [ + "\nReport metrics back to the A/B testing service to measure the conversion rate for each variation in the experiment." + ], + "signature": [ + "(metric: ", + { + "pluginId": "cloudExperiments", + "scope": "common", + "docId": "kibCloudExperimentsPluginApi", + "section": "def-common.CloudExperimentsMetric", + "text": "CloudExperimentsMetric" + }, + ") => void" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsPluginStart.reportMetric.$1", + "type": "Object", + "tags": [], + "label": "metric", + "description": [ + "{@link CloudExperimentsMetric }" + ], + "signature": [ + { + "pluginId": "cloudExperiments", + "scope": "common", + "docId": "kibCloudExperimentsPluginApi", + "section": "def-common.CloudExperimentsMetric", + "text": "CloudExperimentsMetric" + }, + "" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsFeatureFlagNames", + "type": "Type", + "tags": [], + "label": "CloudExperimentsFeatureFlagNames", + "description": [ + "\nThe names of the feature flags declared in Kibana.\nValid keys are defined in {@link FEATURE_FLAG_NAMES}. When using a new feature flag, add the name to the list.\n" + ], + "signature": [ + "\"security-solutions.add-integrations-url\"" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "cloudExperiments", + "id": "def-common.CloudExperimentsMetricNames", + "type": "Type", + "tags": [], + "label": "CloudExperimentsMetricNames", + "description": [ + "\nThe names of the metrics declared in Kibana.\nValid keys are defined in {@link METRIC_NAMES}. When reporting a new metric, add the name to the list.\n" + ], + "signature": [ + "never" + ], + "path": "x-pack/plugins/cloud_integrations/cloud_experiments/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx new file mode 100644 index 0000000000000..f80478c49dede --- /dev/null +++ b/api_docs/cloud_experiments.mdx @@ -0,0 +1,33 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibCloudExperimentsPluginApi +slug: /kibana-dev-docs/api/cloudExperiments +title: "cloudExperiments" +image: https://source.unsplash.com/400x175/?github +description: API docs for the cloudExperiments plugin +date: 2022-09-21 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] +--- +import cloudExperimentsObj from './cloud_experiments.devdocs.json'; + +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. + +Contact [Kibana Core](https://github.com/orgs/elastic/teams/@elastic/kibana-core) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 16 | 0 | 0 | 0 | + +## Common + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index beeef9814456f..8e2501623ac24 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 266884e1d4607..5d4888478dedf 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 6e0b9d0ebebfd..51aa262c87e5a 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json index dd0a8f399f350..ce4999200ef16 100644 --- a/api_docs/core.devdocs.json +++ b/api_docs/core.devdocs.json @@ -11219,6 +11219,14 @@ "plugin": "graph", "path": "x-pack/plugins/graph/public/helpers/saved_workspace_utils.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts" + }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/saved_object/saved_object.test.ts" @@ -11899,6 +11907,69 @@ ], "returnComment": [] }, + { + "parentPluginId": "core", + "id": "def-public.SavedObjectsClientContract.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\nDeletes multiple documents at once" + ], + "signature": [ + "(objects: ", + "SavedObjectTypeIdTuple", + "[], options?: ", + "SavedObjectsBulkDeleteOptions", + " | undefined) => Promise<", + "SavedObjectsBulkDeleteResponse", + ">" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-browser/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-public.SavedObjectsClientContract.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [ + "- an array of objects containing id, type" + ], + "signature": [ + "SavedObjectTypeIdTuple", + "[]" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-browser/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-public.SavedObjectsClientContract.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [ + "- optional force argument to force deletion of objects in a namespace other than the scoped client" + ], + "signature": [ + "SavedObjectsBulkDeleteOptions", + " | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-browser/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [ + "The bulk delete result for the saved objects for the given types and ids." + ] + }, { "parentPluginId": "core", "id": "def-public.SavedObjectsClientContract.find", @@ -15423,7 +15494,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\" | \"css\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -15464,7 +15535,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\" | \"css\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -17831,6 +17902,63 @@ ], "returnComment": [] }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsRepository.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\n {@inheritDoc ISavedObjectsRepository.bulkDelete}" + ], + "signature": [ + "(objects: ", + "SavedObjectsBulkDeleteObject", + "[], options?: ", + "SavedObjectsBulkDeleteOptions", + " | undefined) => Promise<", + "SavedObjectsBulkDeleteResponse", + ">" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server-internal/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsRepository.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteObject", + "[]" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server-internal/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsRepository.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteOptions", + " | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server-internal/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, { "parentPluginId": "core", "id": "def-server.SavedObjectsRepository.deleteByNamespace", @@ -22645,6 +22773,104 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "core", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.total", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.total'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "node_modules/@types/kbn__core-usage-data-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.default.total", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.default.total'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "node_modules/@types/kbn__core-usage-data-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.yes", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.yes'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "node_modules/@types/kbn__core-usage-data-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.no", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.no'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "node_modules/@types/kbn__core-usage-data-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.custom.total", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.custom.total'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "node_modules/@types/kbn__core-usage-data-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.yes", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.yes'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "node_modules/@types/kbn__core-usage-data-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.no", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.no'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "node_modules/@types/kbn__core-usage-data-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "core", "id": "def-server.CoreUsageStats.apiCalls.savedObjectsCreate.total", @@ -30442,6 +30668,67 @@ ], "returnComment": [] }, + { + "parentPluginId": "core", + "id": "def-server.ISavedObjectsRepository.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\nDeletes multiple documents at once" + ], + "signature": [ + "(objects: ", + "SavedObjectsBulkDeleteObject", + "[], options?: ", + "SavedObjectsBulkDeleteOptions", + " | undefined) => Promise<", + "SavedObjectsBulkDeleteResponse", + ">" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.ISavedObjectsRepository.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [ + "- an array of objects containing id and type" + ], + "signature": [ + "SavedObjectsBulkDeleteObject", + "[]" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.ISavedObjectsRepository.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteOptions", + " | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [ + "- { statuses: [{ id, type, success, error: { message } }] }" + ] + }, { "parentPluginId": "core", "id": "def-server.ISavedObjectsRepository.deleteByNamespace", @@ -40565,6 +40852,14 @@ "plugin": "graph", "path": "x-pack/plugins/graph/public/helpers/saved_workspace_utils.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts" + }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/saved_object/saved_object.test.ts" @@ -41252,6 +41547,131 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteObject", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteObject", + "description": [ + "\n" + ], + "signature": [ + "SavedObjectsBulkDeleteObject" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteObject.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteObject.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteOptions", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteOptions", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteOptions", + " extends ", + "SavedObjectsBaseOptions" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteOptions.refresh", + "type": "CompoundType", + "tags": [], + "label": "refresh", + "description": [ + "The Elasticsearch Refresh setting for this operation" + ], + "signature": [ + "MutatingOperationRefreshSetting", + " | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteOptions.force", + "type": "CompoundType", + "tags": [], + "label": "force", + "description": [ + "\nForce deletion of all objects that exists in multiple namespaces, applied to all objects." + ], + "signature": [ + "boolean | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteResponse", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteResponse", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteResponse" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsBulkDeleteResponse.statuses", + "type": "Array", + "tags": [], + "label": "statuses", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteStatus", + "[]" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "core", "id": "def-server.SavedObjectsBulkGetObject", @@ -41931,6 +42351,63 @@ ], "returnComment": [] }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsClientContract.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\nDeletes multiple SavedObjects batched together as a single request\n" + ], + "signature": [ + "(objects: ", + "SavedObjectsBulkDeleteObject", + "[], options?: ", + "SavedObjectsBulkDeleteOptions", + " | undefined) => Promise<", + "SavedObjectsBulkDeleteResponse", + ">" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsClientContract.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteObject", + "[]" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "core", + "id": "def-server.SavedObjectsClientContract.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteOptions", + " | undefined" + ], + "path": "node_modules/@types/kbn__core-saved-objects-api-server/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, { "parentPluginId": "core", "id": "def-server.SavedObjectsClientContract.find", diff --git a/api_docs/core.mdx b/api_docs/core.mdx index ccf426c9b6909..a5cd7b55e96a4 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2657 | 0 | 45 | 2 | +| 2684 | 0 | 45 | 0 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 6407c53bc8db9..cc8febab951ca 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: 2022-09-20 +date: 2022-09-21 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 53da1adcb0d6e..a1e2f06b410e5 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: 2022-09-20 +date: 2022-09-21 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 d39b30e5de370..ed8980fc7c838 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 5c4d12a6cb3d5..cb7c49f026491 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: 2022-09-20 +date: 2022-09-21 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 09c1081a7ca5a..dfc44a7ebf77d 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: 2022-09-20 +date: 2022-09-21 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 3c16e2d5fedae..fa49792d2181c 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: 2022-09-20 +date: 2022-09-21 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 21f01d16fd2a4..15d7ddfaff816 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: 2022-09-20 +date: 2022-09-21 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 cbfd433f1a095..cd3ddbce16f08 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: 2022-09-20 +date: 2022-09-21 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 b47e57d899dc9..706182af7954b 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: 2022-09-20 +date: 2022-09-21 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 0ba596a1b00b6..9394b62cc1a9c 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -17409,7 +17409,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\" | \"css\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -21334,7 +21334,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\" | \"css\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index cea8ef1557292..95d0e05ecf2ab 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: 2022-09-20 +date: 2022-09-21 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 e415597a7fcb6..73e19b646e6f6 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: 2022-09-20 +date: 2022-09-21 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 2ca8394737f06..26c1133aa166d 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -43,7 +43,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | visTypeTimeseries, graph, dataViewManagement, dataViews | - | | | visTypeTimeseries, graph, dataViewManagement, dataViews | - | | | visTypeTimeseries, graph, dataViewManagement | - | -| | lens, observability, dataVisualizer, fleet, cloudSecurityPosture, discoverEnhanced, osquery, synthetics | - | +| | observability, dataVisualizer, fleet, cloudSecurityPosture, discoverEnhanced, osquery, synthetics | - | | | dataViewManagement, dataViews | - | | | dataViews, dataViewManagement | - | | | dataViewManagement, dataViews | - | @@ -62,13 +62,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | canvas | - | | | canvas | - | | | canvas | - | +| | cloud | - | | | spaces, savedObjectsManagement | - | | | spaces, savedObjectsManagement | - | | | actions, ml, savedObjectsTagging, enterpriseSearch | - | | | enterpriseSearch | - | | | console, @kbn/core-elasticsearch-server-internal | - | | | spaces, security, alerting | 8.8.0 | -| | spaces, security, actions, alerting, ml, remoteClusters, graph, indexLifecycleManagement, mapsEms, painlessLab, rollup, searchprofiler, snapshotRestore, transform, upgradeAssistant | 8.8.0 | +| | spaces, security, actions, alerting, ml, remoteClusters, graph, indexLifecycleManagement, mapsEms, painlessLab, rollup, searchprofiler, securitySolution, snapshotRestore, transform, upgradeAssistant | 8.8.0 | | | embeddable, discover, presentationUtil, dashboard, graph | 8.8.0 | | | apm, security, securitySolution | 8.8.0 | | | apm, security, securitySolution | 8.8.0 | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 2d9fa24ea5276..33ca134222c20 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -178,6 +178,7 @@ so TS and code-reference navigation might not highlight them. | | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/public/plugin.tsx#:~:text=environment) | 8.8.0 | +| | [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/public/plugin.tsx#:~:text=identifyUser), [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/server/plugin.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/public/plugin.test.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/public/plugin.test.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/public/plugin.test.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/public/plugin.test.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/server/plugin.test.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/server/plugin.test.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/server/plugin.test.ts#:~:text=identifyUser), [plugin.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/server/plugin.test.ts#:~:text=identifyUser) | - | | | [chat.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud/server/routes/chat.ts#:~:text=authc) | - | @@ -430,7 +431,6 @@ so TS and code-reference navigation might not highlight them. | | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=indexPatternId) | - | | | [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave) | 8.8.0 | @@ -655,11 +655,12 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | | [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/hooks/eql/api.ts#:~:text=options) | - | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [list.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/list.test.ts#:~:text=mode), [response_actions.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts#:~:text=mode)+ 3 more | 8.8.0 | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [list.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/list.test.ts#:~:text=mode), [response_actions.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts#:~:text=mode)+ 3 more | 8.8.0 | +| | [query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/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), [request_context_factory.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/request_context_factory.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), [preview_rules_route.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts#:~:text=authc), [common.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts#:~:text=authc) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/index.tsx#:~:text=onAppLeave), [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/plugin.tsx#:~:text=onAppLeave) | 8.8.0 | | | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx#:~:text=AppLeaveHandler), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/types.ts#:~:text=AppLeaveHandler), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/types.ts#:~:text=AppLeaveHandler), [routes.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/routes.tsx#:~:text=AppLeaveHandler), [routes.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/routes.tsx#:~:text=AppLeaveHandler), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=AppLeaveHandler), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=AppLeaveHandler), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=AppLeaveHandler) | 8.8.0 | -| | [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes) | - | -| | [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes) | - | +| | [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes), [saved_objects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts#:~:text=SavedObjectAttributes), [saved_objects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts#:~:text=SavedObjectAttributes) | - | +| | [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes), [legacy_migrations.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts#:~:text=SavedObjectAttributes), [saved_objects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts#:~:text=SavedObjectAttributes), [saved_objects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/saved_objects.ts#:~:text=SavedObjectAttributes) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 6275c5e9b7f53..a7dc1bdec8678 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -167,6 +167,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | --------|-------|-----------|-----------| | securitySolution | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [list.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/list.test.ts#:~:text=mode), [response_actions.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts#:~:text=mode)+ 3 more | 8.8.0 | | securitySolution | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [list.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/list.test.ts#:~:text=mode), [response_actions.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts#:~:text=mode)+ 3 more | 8.8.0 | +| securitySolution | | [query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts#:~:text=license%24) | 8.8.0 | | securitySolution | | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/index.tsx#:~:text=onAppLeave), [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/plugin.tsx#:~:text=onAppLeave) | 8.8.0 | | securitySolution | | [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx#:~:text=AppLeaveHandler), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/types.ts#:~:text=AppLeaveHandler), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/types.ts#:~:text=AppLeaveHandler), [routes.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/routes.tsx#:~:text=AppLeaveHandler), [routes.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/routes.tsx#:~:text=AppLeaveHandler), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=AppLeaveHandler), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=AppLeaveHandler), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=AppLeaveHandler) | 8.8.0 | @@ -193,5 +194,5 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| -| lens | | [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave) | 8.8.0 | -| management | | [application.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/management/public/application.tsx#:~:text=appBasePath) | 8.8.0 | \ No newline at end of file +| management | | [application.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/management/public/application.tsx#:~:text=appBasePath) | 8.8.0 | +| visualizations | | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave) | 8.8.0 | \ No newline at end of file diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index f43e7dccfe704..08b245fb26f43 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.devdocs.json b/api_docs/discover.devdocs.json index c9ebfdee37434..695319775e984 100644 --- a/api_docs/discover.devdocs.json +++ b/api_docs/discover.devdocs.json @@ -312,10 +312,6 @@ "deprecated": true, "trackAdoption": false, "references": [ - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx" - }, { "plugin": "observability", "path": "x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_discover_link.tsx" @@ -362,6 +358,27 @@ } ] }, + { + "parentPluginId": "discover", + "id": "def-public.DiscoverAppLocatorParams.dataViewSpec", + "type": "Object", + "tags": [], + "label": "dataViewSpec", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewSpec", + "text": "DataViewSpec" + }, + " | undefined" + ], + "path": "src/plugins/discover/public/locator.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "discover", "id": "def-public.DiscoverAppLocatorParams.timeRange", diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index d0066edd11e12..22482b37187c2 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-disco | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 96 | 0 | 79 | 4 | +| 97 | 0 | 80 | 4 | ## Client diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 7b8b8601af087..e29728560aab4 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index d938439ede797..2f5fbce453b35 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index bf199f204fba2..57604fa09d9cc 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: 2022-09-20 +date: 2022-09-21 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 19aca55bed367..10e8ab28d577a 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index a7d4bd56a4065..d21f75ff234d8 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: 2022-09-20 +date: 2022-09-21 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 24b08955cb1ab..799b9e84cc1fd 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: 2022-09-20 +date: 2022-09-21 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 35e2988d5b946..0bf1025c1dd96 100644 --- a/api_docs/event_annotation.devdocs.json +++ b/api_docs/event_annotation.devdocs.json @@ -607,7 +607,7 @@ "label": "AvailableAnnotationIcon", "description": [], "signature": [ - "\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\"" + "\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\"" ], "path": "src/plugins/event_annotation/common/types.ts", "deprecated": false, @@ -1361,7 +1361,7 @@ "label": "options", "description": [], "signature": [ - "(\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\")[]" + "(\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\")[]" ], "path": "src/plugins/event_annotation/common/manual_event_annotation/index.ts", "deprecated": false, @@ -2471,7 +2471,7 @@ "label": "options", "description": [], "signature": [ - "(\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\")[]" + "(\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\")[]" ], "path": "src/plugins/event_annotation/common/query_point_event_annotation/index.ts", "deprecated": false, diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index d5e087678a1d0..b856ac4924147 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index d730f68e18eab..12011c049c6f6 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index a3ee129f44d7a..04fb06c8c96d4 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: 2022-09-20 +date: 2022-09-21 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 3b708aa6953ee..d0b10885cf2b7 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: 2022-09-20 +date: 2022-09-21 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 3a813a40fc8f4..de91bc5178131 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: 2022-09-20 +date: 2022-09-21 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 9c315a54f4499..1cc9d08db5a90 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: 2022-09-20 +date: 2022-09-21 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 b821534dec8b8..9fcf50bff28ef 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: 2022-09-20 +date: 2022-09-21 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 45ed0cf31366f..bc16b14f88d03 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: 2022-09-20 +date: 2022-09-21 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 c9463ec11ba52..7b72a487826e6 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: 2022-09-20 +date: 2022-09-21 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 1518c761b6a23..c219691750f84 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: 2022-09-20 +date: 2022-09-21 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 0f12cfcfe0367..6929d4d65ff1c 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: 2022-09-20 +date: 2022-09-21 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 74cf96e0e3b2c..cf8447fa6e554 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: 2022-09-20 +date: 2022-09-21 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 2897faff88580..b86adf33d39e5 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: 2022-09-20 +date: 2022-09-21 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 c4dd54fe09f32..3fe265b6ba374 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.devdocs.json b/api_docs/expression_x_y.devdocs.json index 46ce5d448b1e5..70749833d4563 100644 --- a/api_docs/expression_x_y.devdocs.json +++ b/api_docs/expression_x_y.devdocs.json @@ -1939,7 +1939,7 @@ "label": "AvailableReferenceLineIcon", "description": [], "signature": [ - "\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"tag\" | \"triangle\" | \"empty\"" + "\"circle\" | \"asterisk\" | \"alert\" | \"bell\" | \"bolt\" | \"bug\" | \"editorComment\" | \"flag\" | \"heart\" | \"mapMarker\" | \"pinFilled\" | \"starEmpty\" | \"starFilled\" | \"tag\" | \"triangle\" | \"empty\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index d94ee04294bb3..c017cb7f59f51 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: 2022-09-20 +date: 2022-09-21 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 3d4b511820a01..8bd22f5dbc372 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: 2022-09-20 +date: 2022-09-21 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 4589136f7b707..fb97fac6d9a73 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: 2022-09-20 +date: 2022-09-21 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 0583d1db89a25..02113ea2e591b 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: 2022-09-20 +date: 2022-09-21 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 260869a64bd85..3a28e7c492bf3 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: 2022-09-20 +date: 2022-09-21 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 98d50b6c79efc..bb3bd2bbcff56 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index 24e0f4dce933a..66f288b6ca432 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -5690,6 +5690,167 @@ ], "returnComment": [] }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate", + "type": "Function", + "tags": [], + "label": "bulkUpdate", + "description": [], + "signature": [ + "(soClient: ", + "SavedObjectsClientContract", + ", esClient: ", + "ElasticsearchClient", + ", packagePolicyUpdates: (", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.NewPackagePolicy", + "text": "NewPackagePolicy" + }, + " & { version?: string | undefined; id: string; })[], options?: { user?: ", + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, + " | undefined; force?: boolean | undefined; } | undefined, currentVersion?: string | undefined) => Promise<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackagePolicy", + "text": "PackagePolicy" + }, + "[] | null>" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate.$1", + "type": "Object", + "tags": [], + "label": "soClient", + "description": [], + "signature": [ + "SavedObjectsClientContract" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate.$2", + "type": "Object", + "tags": [], + "label": "esClient", + "description": [], + "signature": [ + "ElasticsearchClient" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate.$3", + "type": "Array", + "tags": [], + "label": "packagePolicyUpdates", + "description": [], + "signature": [ + "(", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.NewPackagePolicy", + "text": "NewPackagePolicy" + }, + " & { version?: string | undefined; id: string; })[]" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate.$4", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate.$4.user", + "type": "Object", + "tags": [], + "label": "user", + "description": [], + "signature": [ + { + "pluginId": "security", + "scope": "common", + "docId": "kibSecurityPluginApi", + "section": "def-common.AuthenticatedUser", + "text": "AuthenticatedUser" + }, + " | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate.$4.force", + "type": "CompoundType", + "tags": [], + "label": "force", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.bulkUpdate.$5", + "type": "string", + "tags": [], + "label": "currentVersion", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, { "parentPluginId": "fleet", "id": "def-server.PackagePolicyClient.get", @@ -8856,6 +9017,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "fleet", + "id": "def-common.EpmPackageAdditions.licensePath", + "type": "string", + "tags": [], + "label": "licensePath", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/epm.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "fleet", "id": "def-common.EpmPackageAdditions.keepPoliciesUpToDate", @@ -12122,6 +12297,48 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.PackageSpecConditions", + "type": "Interface", + "tags": [], + "label": "PackageSpecConditions", + "description": [], + "path": "x-pack/plugins/fleet/common/types/models/package_spec.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.PackageSpecConditions.kibana", + "type": "Object", + "tags": [], + "label": "kibana", + "description": [], + "signature": [ + "{ version: string; }" + ], + "path": "x-pack/plugins/fleet/common/types/models/package_spec.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.PackageSpecConditions.elastic", + "type": "Object", + "tags": [], + "label": "elastic", + "description": [], + "signature": [ + "{ subscription: string; } | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/package_spec.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.PackageSpecIcon", @@ -12269,6 +12486,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "fleet", + "id": "def-common.PackageSpecManifest.source", + "type": "Object", + "tags": [], + "label": "source", + "description": [], + "signature": [ + "{ license: string; } | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/package_spec.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "fleet", "id": "def-common.PackageSpecManifest.type", @@ -13827,7 +14058,7 @@ "label": "DocAssetType", "description": [], "signature": [ - "\"notice\" | \"doc\"" + "\"license\" | \"notice\" | \"doc\"" ], "path": "x-pack/plugins/fleet/common/types/models/epm.ts", "deprecated": false, @@ -14859,21 +15090,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "fleet", - "id": "def-common.PackageSpecConditions", - "type": "Type", - "tags": [], - "label": "PackageSpecConditions", - "description": [], - "signature": [ - "{ kibana: { version: string; }; }" - ], - "path": "x-pack/plugins/fleet/common/types/models/package_spec.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "fleet", "id": "def-common.PLUGIN_ID", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 398f9e82fd03a..07f8d74f9c842 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 974 | 3 | 874 | 17 | +| 986 | 3 | 886 | 17 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index c71484128ec3b..c5034da58e5a1 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: 2022-09-20 +date: 2022-09-21 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 e7625a590a461..fe535e96c2df8 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: 2022-09-20 +date: 2022-09-21 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 381a739739e54..1c29739eb6bb6 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index ed831349e52bd..501b570f5d017 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: 2022-09-20 +date: 2022-09-21 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 c8af6660752e5..c01e2fd84fcd7 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: 2022-09-20 +date: 2022-09-21 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 27f5c3569fa49..8a0e939a8ed2b 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: 2022-09-20 +date: 2022-09-21 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 18fb173160a21..b0b1c0aba0443 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: 2022-09-20 +date: 2022-09-21 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 9056c00d72b84..32e01d93df529 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: 2022-09-20 +date: 2022-09-21 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 9858dd71b40a0..376fd853d73aa 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: 2022-09-20 +date: 2022-09-21 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 d20a7b9ad37dd..dc1ee35a57b69 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: 2022-09-20 +date: 2022-09-21 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 091fed52214f6..b87509e3cc43f 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index adcc61574b831..0d305dac2e069 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index d946f4c837ceb..873c79fa16586 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: 2022-09-20 +date: 2022-09-21 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 d39f68906c4e7..a4f4547481fd4 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: 2022-09-20 +date: 2022-09-21 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 cd98524289903..382a8ad33ef27 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: 2022-09-20 +date: 2022-09-21 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 fe6b3d629f334..e1eccc8fdb940 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: 2022-09-20 +date: 2022-09-21 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 b5f8465d23abb..dac62dbfa13f6 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: 2022-09-20 +date: 2022-09-21 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 f0bf230c94525..2f3a2e4b6e791 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index e05ed7932ea0b..948d34bfbcbd4 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: 2022-09-20 +date: 2022-09-21 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 9f1463f50f008..92e27ecd44c61 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 350dfc4f21573..5901d75a22dfe 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: 2022-09-20 +date: 2022-09-21 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 fe78eade4d5e8..3d141045316e9 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 1fd328a1909af..c4bf743890b27 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: 2022-09-20 +date: 2022-09-21 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 36f3f627a7079..e80b8d319443f 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: 2022-09-20 +date: 2022-09-21 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 66064bc9235db..dcf4e1168cda0 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: 2022-09-20 +date: 2022-09-21 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 50c89a112f318..b0d2e856b602b 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: 2022-09-20 +date: 2022-09-21 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 946811ebef1ef..af88a7a61ecaf 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index e1e61842963b9..d179dd6f56b8d 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: 2022-09-20 +date: 2022-09-21 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 f4e1d6df66d36..610cf11db4ce2 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: 2022-09-20 +date: 2022-09-21 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 3dfe88a5fe6f8..9796cc2ef31a2 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: 2022-09-20 +date: 2022-09-21 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 770caaadc3273..be242a54c53a0 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index 88c8770f78e05..d36ee3d0a04b8 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: 2022-09-20 +date: 2022-09-21 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_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 9985d16c3d530..92f03112a75e2 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: 2022-09-20 +date: 2022-09-21 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 8b30598c799c5..5ee4fe180b1a6 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: 2022-09-20 +date: 2022-09-21 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 7d9ba2b790cd9..ddab8a6da8ba5 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: 2022-09-20 +date: 2022-09-21 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 367e2d1efc34b..3cf2b1c781613 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: 2022-09-20 +date: 2022-09-21 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 3bc7041adc0c7..1978fd217005e 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: 2022-09-20 +date: 2022-09-21 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 04c9d11050656..f921a117aa1ac 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: 2022-09-20 +date: 2022-09-21 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 d334e274ebd27..27c1ae53f78c0 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: 2022-09-20 +date: 2022-09-21 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 fb1732696cd58..2fef5d62c1be4 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: 2022-09-20 +date: 2022-09-21 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 5841b62fe8421..fd1a6a7790662 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: 2022-09-20 +date: 2022-09-21 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 d24d2537e5a29..e323813393c86 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: 2022-09-20 +date: 2022-09-21 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 ac8c8304cbacd..8e7baa413c2d9 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: 2022-09-20 +date: 2022-09-21 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 d379d0650b330..37560d75caaa7 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: 2022-09-20 +date: 2022-09-21 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_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 1532b48e1caa7..b3de07059b8b3 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: 2022-09-20 +date: 2022-09-21 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 7ae08ec040bc7..bccffa5f3169b 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: 2022-09-20 +date: 2022-09-21 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 a46e1f96ce169..2d70af69f3207 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: 2022-09-20 +date: 2022-09-21 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 c4ade5b2f59e7..92b87e2784eb8 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: 2022-09-20 +date: 2022-09-21 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 734a7db43b735..36b71dc6bbf18 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: 2022-09-20 +date: 2022-09-21 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 b039c307cc98d..8840046d85094 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: 2022-09-20 +date: 2022-09-21 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 e53c2bfaa2f7c..d829790191100 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: 2022-09-20 +date: 2022-09-21 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 dba1d83d54bfa..ea0cddb465a58 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: 2022-09-20 +date: 2022-09-21 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 0b8ccf9d5cc52..47c38a7c769e9 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: 2022-09-20 +date: 2022-09-21 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 c9b340d67fa0e..28553cc4442de 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: 2022-09-20 +date: 2022-09-21 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 00e6556403379..e3121dd71a4c5 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: 2022-09-20 +date: 2022-09-21 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_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 8c6a0d2cc5326..51ab765a1ebfd 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: 2022-09-20 +date: 2022-09-21 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 fcf11ae9ddef9..2aca3e87366d5 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: 2022-09-20 +date: 2022-09-21 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 9c728cc39d05c..1de746416ab97 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: 2022-09-20 +date: 2022-09-21 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 57a9e5d36f00e..a8eba9d98e241 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: 2022-09-20 +date: 2022-09-21 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 579e0c95cedd1..df85327dc4356 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: 2022-09-20 +date: 2022-09-21 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 6f67e55a17c96..a90ff68ad7816 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: 2022-09-20 +date: 2022-09-21 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 9f3766a0e2e9a..8970c1fb4c739 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: 2022-09-20 +date: 2022-09-21 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 f3c49ab467f46..ca61cd3b1df6c 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: 2022-09-20 +date: 2022-09-21 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 601595113c8bd..593f2f23e1172 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: 2022-09-20 +date: 2022-09-21 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 b8dbcf387129b..1b6fc98e5aaa8 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: 2022-09-20 +date: 2022-09-21 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 d9e077756915d..58d6dab3192fc 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: 2022-09-20 +date: 2022-09-21 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 9de0e77f1d83b..bdaea106a91d2 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: 2022-09-20 +date: 2022-09-21 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 7b77b445df55e..82dfdc3bf2116 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: 2022-09-20 +date: 2022-09-21 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 226141067a8d8..53c51781010a0 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: 2022-09-20 +date: 2022-09-21 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 44deabd806282..a8b0c0db5b795 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: 2022-09-20 +date: 2022-09-21 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 4588b1e74c0fc..aa122cf8c7e6e 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: 2022-09-20 +date: 2022-09-21 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 14d84cfd0c01e..a22516bdc6e0e 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: 2022-09-20 +date: 2022-09-21 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 34101622d0bb1..a51d321654147 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: 2022-09-20 +date: 2022-09-21 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 8412cea09e8dc..458d203e20aa7 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: 2022-09-20 +date: 2022-09-21 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 a488597af297c..cc444c3d5b8ca 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: 2022-09-20 +date: 2022-09-21 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 906e6aa1e6d33..3bc9d80c72a18 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: 2022-09-20 +date: 2022-09-21 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 25cbf34eaceb0..d29a114050dbf 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: 2022-09-20 +date: 2022-09-21 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 430afd1e0013b..4509eb592b397 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: 2022-09-20 +date: 2022-09-21 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 34072ca6dfde7..af698072a94ca 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: 2022-09-20 +date: 2022-09-21 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 4d424546b14b7..eb5d40300ed87 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: 2022-09-20 +date: 2022-09-21 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 4ea933853df2d..4cff04d98dc26 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: 2022-09-20 +date: 2022-09-21 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 397f9e99b4924..721ea0c3945d9 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: 2022-09-20 +date: 2022-09-21 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 c781ba9fff5a3..415f15276d937 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: 2022-09-20 +date: 2022-09-21 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 0be92db2558f6..6db848c711182 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: 2022-09-20 +date: 2022-09-21 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 06d2f6cda8dbb..573f8733da5b5 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: 2022-09-20 +date: 2022-09-21 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 1bccc28f3add7..b883779a793a0 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: 2022-09-20 +date: 2022-09-21 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 889dd33ec6144..d18c50836ba87 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: 2022-09-20 +date: 2022-09-21 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_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index d6bf834e28d3f..3d126a078dc71 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: 2022-09-20 +date: 2022-09-21 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 02de9f766f698..faa4e8f8e4e0d 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: 2022-09-20 +date: 2022-09-21 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 fd40adbec69d3..d2614fafeaf5f 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: 2022-09-20 +date: 2022-09-21 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 c7c396db97c20..9051a0bf0b52e 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: 2022-09-20 +date: 2022-09-21 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 ca70a925fbb56..c9419dbd572a9 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: 2022-09-20 +date: 2022-09-21 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 3660bcc446cf5..b1dba4af85762 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: 2022-09-20 +date: 2022-09-21 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 75e85149ca6c4..b67a590ecfa75 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: 2022-09-20 +date: 2022-09-21 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 a5f96ecfd44b4..2dd6083d4293f 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: 2022-09-20 +date: 2022-09-21 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 497956f0ee8a3..ae5f69bf3d5bf 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: 2022-09-20 +date: 2022-09-21 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 24e3538122a9d..b16d6e10e8725 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: 2022-09-20 +date: 2022-09-21 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.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index 58b512d1545c7..a1c0750d2f77b 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] --- import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.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 de5f52b8471e4..c733e3cc061a7 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: 2022-09-20 +date: 2022-09-21 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 0637bb9d8925e..cc3c1aae43229 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: 2022-09-20 +date: 2022-09-21 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 3e7b806dc160a..f303a7a2bce56 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: 2022-09-20 +date: 2022-09-21 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_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 55eb0c12108de..500ece47590d2 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: 2022-09-20 +date: 2022-09-21 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 f50fbbca7396c..34db9ddb92aa6 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: 2022-09-20 +date: 2022-09-21 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 a674bd9826403..8736af0225f13 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: 2022-09-20 +date: 2022-09-21 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 24e800f05030e..f1ff3c7382729 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: 2022-09-20 +date: 2022-09-21 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 6d04faa001d5a..9aebf6bfe65fa 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: 2022-09-20 +date: 2022-09-21 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 67c149514411e..d9ab077872da7 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: 2022-09-20 +date: 2022-09-21 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 aae45e4a49448..bd4671af281c4 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: 2022-09-20 +date: 2022-09-21 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 99a09376c4b9b..22cc5dac4f43d 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: 2022-09-20 +date: 2022-09-21 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 fb1266aaba745..cfe0c1672a0ac 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: 2022-09-20 +date: 2022-09-21 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 b3f8467f9f307..d6f58108da44a 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: 2022-09-20 +date: 2022-09-21 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 d0b884478e8d8..5aa0b5bf3138c 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: 2022-09-20 +date: 2022-09-21 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 4374729c68ce3..59e3b1e657613 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: 2022-09-20 +date: 2022-09-21 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.devdocs.json b/api_docs/kbn_core_notifications_browser.devdocs.json index b69e0619012a3..c9bcfa0a110d8 100644 --- a/api_docs/kbn_core_notifications_browser.devdocs.json +++ b/api_docs/kbn_core_notifications_browser.devdocs.json @@ -681,7 +681,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\" | \"css\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", @@ -728,7 +728,7 @@ "signature": [ "Pick<", "Toast", - ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\"> & { title?: string | ", + ", \"children\" | \"onError\" | \"hidden\" | \"color\" | \"className\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"toastLifeTimeMs\" | \"iconType\" | \"onClose\" | \"data-test-subj\" | \"css\"> & { title?: string | ", "MountPoint", " | undefined; text?: string | ", "MountPoint", diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index ed6b7c356b79f..a17faa06bcc22 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: 2022-09-20 +date: 2022-09-21 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 4e05d51b17b25..6b5aaa33c88c7 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: 2022-09-20 +date: 2022-09-21 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 0b13cdbd31306..daf8186f94e4f 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: 2022-09-20 +date: 2022-09-21 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 8f1a0f8bbbbad..7a5eff7a76390 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: 2022-09-20 +date: 2022-09-21 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 15b9282a5911d..8c8a72aa73172 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: 2022-09-20 +date: 2022-09-21 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 1e7f0b4206b89..ec24423b0c296 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: 2022-09-20 +date: 2022-09-21 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_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 7e9afcaea1185..e6385a2a75836 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: 2022-09-20 +date: 2022-09-21 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 0aea4d9e2256a..0c8abfaa31f78 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: 2022-09-20 +date: 2022-09-21 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 87ef4b638ae7b..98ee357d65bf7 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: 2022-09-20 +date: 2022-09-21 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_saved_objects_api_browser.devdocs.json b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json index 2e6c45ada0542..b12a698b21606 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json @@ -248,6 +248,131 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteOptions", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteOptions", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteOptions.force", + "type": "CompoundType", + "tags": [], + "label": "force", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteResponse", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteResponse", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteResponse.statuses", + "type": "Array", + "tags": [], + "label": "statuses", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-browser", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiBrowserPluginApi", + "section": "def-common.SavedObjectsBulkDeleteResponseItem", + "text": "SavedObjectsBulkDeleteResponseItem" + }, + "[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteResponseItem", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteResponseItem", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteResponseItem.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteResponseItem.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteResponseItem.success", + "type": "boolean", + "tags": [], + "label": "success", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsBulkDeleteResponseItem.error", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "SavedObjectError", + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/core-saved-objects-api-browser", "id": "def-common.SavedObjectsBulkResolveResponse", @@ -678,6 +803,87 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsClientContract.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\nDeletes multiple documents at once" + ], + "signature": [ + "(objects: ", + "SavedObjectTypeIdTuple", + "[], options?: ", + { + "pluginId": "@kbn/core-saved-objects-api-browser", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiBrowserPluginApi", + "section": "def-common.SavedObjectsBulkDeleteOptions", + "text": "SavedObjectsBulkDeleteOptions" + }, + " | undefined) => Promise<", + { + "pluginId": "@kbn/core-saved-objects-api-browser", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiBrowserPluginApi", + "section": "def-common.SavedObjectsBulkDeleteResponse", + "text": "SavedObjectsBulkDeleteResponse" + }, + ">" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/saved_objects_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsClientContract.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [ + "- an array of objects containing id, type" + ], + "signature": [ + "SavedObjectTypeIdTuple", + "[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/saved_objects_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-browser", + "id": "def-common.SavedObjectsClientContract.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [ + "- optional force argument to force deletion of objects in a namespace other than the scoped client" + ], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-browser", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiBrowserPluginApi", + "section": "def-common.SavedObjectsBulkDeleteOptions", + "text": "SavedObjectsBulkDeleteOptions" + }, + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-browser/src/saved_objects_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [ + "The bulk delete result for the saved objects for the given types and ids." + ] + }, { "parentPluginId": "@kbn/core-saved-objects-api-browser", "id": "def-common.SavedObjectsClientContract.find", diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index fb16daa874388..a5933775d7f23 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; @@ -21,7 +21,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 94 | 1 | 66 | 0 | +| 106 | 1 | 75 | 0 | ## Common diff --git a/api_docs/kbn_core_saved_objects_api_server.devdocs.json b/api_docs/kbn_core_saved_objects_api_server.devdocs.json index 74d6732ba03ba..0e040b72d2d3d 100644 --- a/api_docs/kbn_core_saved_objects_api_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_server.devdocs.json @@ -444,6 +444,97 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.ISavedObjectsRepository.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\nDeletes multiple documents at once" + ], + "signature": [ + "(objects: ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteObject", + "text": "SavedObjectsBulkDeleteObject" + }, + "[], options?: ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteOptions", + "text": "SavedObjectsBulkDeleteOptions" + }, + " | undefined) => Promise<", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteResponse", + "text": "SavedObjectsBulkDeleteResponse" + }, + ">" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_repository.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.ISavedObjectsRepository.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [ + "- an array of objects containing id and type" + ], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteObject", + "text": "SavedObjectsBulkDeleteObject" + }, + "[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_repository.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.ISavedObjectsRepository.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteOptions", + "text": "SavedObjectsBulkDeleteOptions" + }, + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_repository.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [ + "- { statuses: [{ id, type, success, error: { message } }] }" + ] + }, { "parentPluginId": "@kbn/core-saved-objects-api-server", "id": "def-server.ISavedObjectsRepository.deleteByNamespace", @@ -2131,6 +2222,215 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteObject", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteObject", + "description": [ + "\n" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteObject.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteObject.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteOptions", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteOptions", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteOptions", + "text": "SavedObjectsBulkDeleteOptions" + }, + " extends ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBaseOptions", + "text": "SavedObjectsBaseOptions" + } + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteOptions.refresh", + "type": "CompoundType", + "tags": [], + "label": "refresh", + "description": [ + "The Elasticsearch Refresh setting for this operation" + ], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.MutatingOperationRefreshSetting", + "text": "MutatingOperationRefreshSetting" + }, + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteOptions.force", + "type": "CompoundType", + "tags": [], + "label": "force", + "description": [ + "\nForce deletion of all objects that exists in multiple namespaces, applied to all objects." + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteResponse", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteResponse", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteResponse.statuses", + "type": "Array", + "tags": [], + "label": "statuses", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteStatus", + "text": "SavedObjectsBulkDeleteStatus" + }, + "[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteStatus", + "type": "Interface", + "tags": [], + "label": "SavedObjectsBulkDeleteStatus", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteStatus.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteStatus.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteStatus.success", + "type": "boolean", + "tags": [], + "label": "success", + "description": [ + "The status of deleting the object: true for deleted, false for error" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsBulkDeleteStatus.error", + "type": "Object", + "tags": [], + "label": "error", + "description": [ + "Reason the object could not be deleted (success is false)" + ], + "signature": [ + "SavedObjectError", + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/apis/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/core-saved-objects-api-server", "id": "def-server.SavedObjectsBulkGetObject", @@ -2939,6 +3239,93 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsClientContract.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\nDeletes multiple SavedObjects batched together as a single request\n" + ], + "signature": [ + "(objects: ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteObject", + "text": "SavedObjectsBulkDeleteObject" + }, + "[], options?: ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteOptions", + "text": "SavedObjectsBulkDeleteOptions" + }, + " | undefined) => Promise<", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteResponse", + "text": "SavedObjectsBulkDeleteResponse" + }, + ">" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsClientContract.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteObject", + "text": "SavedObjectsBulkDeleteObject" + }, + "[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server", + "id": "def-server.SavedObjectsClientContract.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "server", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-server.SavedObjectsBulkDeleteOptions", + "text": "SavedObjectsBulkDeleteOptions" + }, + " | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, { "parentPluginId": "@kbn/core-saved-objects-api-server", "id": "def-server.SavedObjectsClientContract.find", diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index f308f99088f93..48aef5d9e3a5a 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; @@ -21,7 +21,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 289 | 1 | 126 | 0 | +| 308 | 1 | 137 | 0 | ## Server diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.devdocs.json b/api_docs/kbn_core_saved_objects_api_server_internal.devdocs.json index d5a95dee2de38..79c17d6086eef 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_server_internal.devdocs.json @@ -278,6 +278,62 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server-internal", + "id": "def-server.SavedObjectsRepository.bulkDelete", + "type": "Function", + "tags": [], + "label": "bulkDelete", + "description": [ + "\n {@inheritDoc ISavedObjectsRepository.bulkDelete}" + ], + "signature": [ + "(objects: ", + "SavedObjectsBulkDeleteObject", + "[], options?: ", + "SavedObjectsBulkDeleteOptions", + ") => Promise<", + "SavedObjectsBulkDeleteResponse", + ">" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/repository.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-api-server-internal", + "id": "def-server.SavedObjectsRepository.bulkDelete.$1", + "type": "Array", + "tags": [], + "label": "objects", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteObject", + "[]" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/repository.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-api-server-internal", + "id": "def-server.SavedObjectsRepository.bulkDelete.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "SavedObjectsBulkDeleteOptions" + ], + "path": "packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/repository.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "@kbn/core-saved-objects-api-server-internal", "id": "def-server.SavedObjectsRepository.deleteByNamespace", diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index f0a6438fc4fa6..8f7fe0f6163f2 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.devdocs.json'; @@ -21,7 +21,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 68 | 0 | 49 | 0 | +| 71 | 0 | 51 | 0 | ## Server 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 387d4624b34cb..738cbc10225ea 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: 2022-09-20 +date: 2022-09-21 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 3fd8a5c5e9c37..d4874ff125c9d 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: 2022-09-20 +date: 2022-09-21 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 96ebbe50c9dbb..6bf81edf60447 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: 2022-09-20 +date: 2022-09-21 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 814bc13c8a0f0..f631627c7c671 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: 2022-09-20 +date: 2022-09-21 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 321a185f26b0c..f8d2a00000ad6 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: 2022-09-20 +date: 2022-09-21 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 0eff5fe3a0815..b2429c7efea6a 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 3543ac5cce759..6942d08a8a361 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: 2022-09-20 +date: 2022-09-21 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 dbb9933bd19ef..80a176a289a2b 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: 2022-09-20 +date: 2022-09-21 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 ee4489e6cee50..87fd03b5794a6 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: 2022-09-20 +date: 2022-09-21 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 f3c16660d9b57..f5c4c8c690179 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: 2022-09-20 +date: 2022-09-21 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 181a58b3b26d0..f2562939d3214 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: 2022-09-20 +date: 2022-09-21 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 9e0a46fb69b22..dca63daba9785 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: 2022-09-20 +date: 2022-09-21 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.devdocs.json b/api_docs/kbn_core_saved_objects_server_internal.devdocs.json index c4872c37e0445..5d601613ed4a7 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.devdocs.json +++ b/api_docs/kbn_core_saved_objects_server_internal.devdocs.json @@ -212,6 +212,56 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/core-saved-objects-server-internal", + "id": "def-server.registerBulkDeleteRoute", + "type": "Function", + "tags": [], + "label": "registerBulkDeleteRoute", + "description": [], + "signature": [ + "(router: ", + "InternalSavedObjectRouter", + ", { coreUsageData }: RouteDependencies) => void" + ], + "path": "packages/core/saved-objects/core-saved-objects-server-internal/src/routes/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-saved-objects-server-internal", + "id": "def-server.registerBulkDeleteRoute.$1", + "type": "Object", + "tags": [], + "label": "router", + "description": [], + "signature": [ + "InternalSavedObjectRouter" + ], + "path": "packages/core/saved-objects/core-saved-objects-server-internal/src/routes/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-saved-objects-server-internal", + "id": "def-server.registerBulkDeleteRoute.$2", + "type": "Object", + "tags": [], + "label": "{ coreUsageData }", + "description": [], + "signature": [ + "RouteDependencies" + ], + "path": "packages/core/saved-objects/core-saved-objects-server-internal/src/routes/bulk_delete.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/core-saved-objects-server-internal", "id": "def-server.registerBulkGetRoute", diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index a4e0fa38d323b..015215fa5039e 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; @@ -21,7 +21,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 66 | 0 | 66 | 4 | +| 69 | 0 | 69 | 4 | ## Server diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 6b1a14d7b5a92..36d189e120cd8 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: 2022-09-20 +date: 2022-09-21 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 cc7cefe0fc9cc..5900ab2e01897 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: 2022-09-20 +date: 2022-09-21 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 36290f4685f52..410b3389b9ef6 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: 2022-09-20 +date: 2022-09-21 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 764213f0fcc65..250cb345b9a21 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: 2022-09-20 +date: 2022-09-21 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 5fa9cf11f74df..9e062fe408eec 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: 2022-09-20 +date: 2022-09-21 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 cd6df67e78030..448c81ec4b79a 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: 2022-09-20 +date: 2022-09-21 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 c2bbd12094c04..3593f09e53c79 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: 2022-09-20 +date: 2022-09-21 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 e8be3567313b0..c1ea683699773 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: 2022-09-20 +date: 2022-09-21 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 6bb448c563b7b..90c31ad1d6e85 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: 2022-09-20 +date: 2022-09-21 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_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index ef68d664af2c1..11ed64d22dcc7 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: 2022-09-20 +date: 2022-09-21 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 978f1833da04a..5cb8a68077a19 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: 2022-09-20 +date: 2022-09-21 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 8abf444a86f18..8b8c6e62c6fc1 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: 2022-09-20 +date: 2022-09-21 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 9ac7e4f27c121..8c4774f561e62 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: 2022-09-20 +date: 2022-09-21 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 8cdfe923481d2..729aa317ec334 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: 2022-09-20 +date: 2022-09-21 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 c82a3ba9a1c82..095a8324b79c3 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: 2022-09-20 +date: 2022-09-21 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 40f540a5048a6..bd961f3cd990a 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: 2022-09-20 +date: 2022-09-21 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 eaeeedee820f9..71f72e035cb74 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: 2022-09-20 +date: 2022-09-21 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 12ade9596f6e6..657ac74105e43 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: 2022-09-20 +date: 2022-09-21 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 931ce804b79eb..50887b10d7a0d 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: 2022-09-20 +date: 2022-09-21 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.devdocs.json b/api_docs/kbn_core_usage_data_server.devdocs.json index 49517d65e5019..99ec8f759c0dd 100644 --- a/api_docs/kbn_core_usage_data_server.devdocs.json +++ b/api_docs/kbn_core_usage_data_server.devdocs.json @@ -834,6 +834,104 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "@kbn/core-usage-data-server", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.total", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.total'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-usage-data-server", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.default.total", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.default.total'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-usage-data-server", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.yes", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.yes'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-usage-data-server", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.no", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.default.kibanaRequest.no'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-usage-data-server", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.custom.total", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.custom.total'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-usage-data-server", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.yes", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.yes'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/core-usage-data-server", + "id": "def-server.CoreUsageStats.apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.no", + "type": "number", + "tags": [], + "label": "'apiCalls.savedObjectsBulkDelete.namespace.custom.kibanaRequest.no'", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/core-usage-data-server", "id": "def-server.CoreUsageStats.apiCalls.savedObjectsCreate.total", diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index 8b6294af5a33a..0c74acc01304f 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; @@ -21,7 +21,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 146 | 0 | 135 | 0 | +| 153 | 0 | 142 | 0 | ## Server diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 971946e462f2f..8e592b7f85eee 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: 2022-09-20 +date: 2022-09-21 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.devdocs.json b/api_docs/kbn_core_usage_data_server_mocks.devdocs.json index 20f3ce6d5b306..0f3cc66101f7f 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.devdocs.json +++ b/api_docs/kbn_core_usage_data_server_mocks.devdocs.json @@ -83,6 +83,8 @@ "BaseIncrementOptions", "]>; incrementSavedObjectsBulkUpdate: jest.MockInstance, [options: ", "BaseIncrementOptions", + "]>; incrementSavedObjectsBulkDelete: jest.MockInstance, [options: ", + "BaseIncrementOptions", "]>; incrementSavedObjectsCreate: jest.MockInstance, [options: ", "BaseIncrementOptions", "]>; incrementSavedObjectsDelete: jest.MockInstance, [options: ", diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 0b31e5b3a34d7..f0a28f0875ed9 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: 2022-09-20 +date: 2022-09-21 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_crypto.mdx b/api_docs/kbn_crypto.mdx index 5b41d00b6b4d9..28faa9e162e77 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: 2022-09-20 +date: 2022-09-21 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 f3389cdd3d2a5..46c98951488ae 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 10bef6d0fe0ef..aa7809f7eb2e1 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: 2022-09-20 +date: 2022-09-21 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 0341bd60eb0db..1843be33150fa 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: 2022-09-20 +date: 2022-09-21 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 9d36428f50b35..17b48fee7a458 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: 2022-09-20 +date: 2022-09-21 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 08ad6b9284437..5df40a7588976 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: 2022-09-20 +date: 2022-09-21 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 703febe0cd967..5340deeed61b7 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: 2022-09-20 +date: 2022-09-21 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 dd0d195749624..4590efe64c129 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: 2022-09-20 +date: 2022-09-21 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 2e041d294ebee..e074495e15334 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 302ca68691fea..79dcf4c12fdba 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index 66d013d8f0a36..bf0588c4f99c1 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: 2022-09-20 +date: 2022-09-21 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 ab88b5be725c4..7ae016edcfb59 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: 2022-09-20 +date: 2022-09-21 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 00b04a4bbc45f..06994c389d718 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.devdocs.json b/api_docs/kbn_es_types.devdocs.json new file mode 100644 index 0000000000000..df40e62edf33b --- /dev/null +++ b/api_docs/kbn_es_types.devdocs.json @@ -0,0 +1,463 @@ +{ + "id": "@kbn/es-types", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.ESSearchOptions", + "type": "Interface", + "tags": [], + "label": "ESSearchOptions", + "description": [], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.ESSearchOptions.restTotalHitsAsInt", + "type": "boolean", + "tags": [], + "label": "restTotalHitsAsInt", + "description": [], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.AggregateOf", + "type": "Type", + "tags": [], + "label": "AggregateOf", + "description": [], + "signature": [ + "Pick & { adjacency_matrix: { buckets: ({ key: string; doc_count: number; } & SubAggregateOf)[]; }; auto_date_histogram: { interval: string; buckets: ({ key: number; key_as_string: string; doc_count: number; } & SubAggregateOf)[]; }; avg: { value: number | null; value_as_string?: string | undefined; }; avg_bucket: { value: number | null; }; boxplot: { min: number | null; max: number | null; q1: number | null; q2: number | null; q3: number | null; }; bucket_correlation: { value: number | null; }; bucket_count_ks_test: { less: number; greater: number; two_sided: number; }; bucket_script: { value: unknown; }; cardinality: { value: number; }; children: { doc_count: number; } & SubAggregateOf; composite: { after_key: CompositeKeysOf; buckets: ({ doc_count: number; key: CompositeKeysOf; } & SubAggregateOf)[]; }; cumulative_cardinality: { value: number; }; cumulative_sum: { value: number; }; date_histogram: MaybeKeyed, string>; date_range: MaybeKeyed & Partial<{ to: string | number; to_as_string: string; }> & { doc_count: number; key: string; }, string>; derivative: { value: number | null; } | undefined; extended_stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_of_squares_as_string: string; variance_population_as_string: string; variance_sampling_as_string: string; std_deviation_as_string: string; std_deviation_population_as_string: string; std_deviation_sampling_as_string: string; std_deviation_bounds_as_string: { upper: string; lower: string; upper_population: string; lower_population: string; upper_sampling: string; lower_sampling: string; }; }); extended_stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number | null; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; }; filter: { doc_count: number; } & SubAggregateOf; filters: { buckets: TAggregationContainer extends { filters: { filters: any[]; }; } ? ({ doc_count: number; } & SubAggregateOf)[] : TAggregationContainer extends { filters: { filters: Record; }; } ? { [key in keyof TAggregationContainer[\"filters\"][\"filters\"]]: { doc_count: number; } & SubAggregateOf; } & (TAggregationContainer extends { filters: { other_bucket_key: infer TOtherBucketKey; }; } ? Record> : unknown) & (TAggregationContainer extends { filters: { other_bucket: true; }; } ? { _other: { doc_count: number; } & SubAggregateOf; } : unknown) : unknown; }; geo_bounds: { top_left: { lat: number | null; lon: number | null; }; bottom_right: { lat: number | null; lon: number | null; }; }; geo_centroid: { count: number; location: { lat: number; lon: number; }; }; geo_distance: MaybeKeyed, string>; geo_hash: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; geotile_grid: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; global: { doc_count: number; } & SubAggregateOf; histogram: MaybeKeyed, string>; ip_range: MaybeKeyed; inference: { value: number; prediction_probability: number; prediction_score: number; }; max: { value: number | null; value_as_string?: string | undefined; }; max_bucket: { value: number | null; }; min: { value: number | null; value_as_string?: string | undefined; }; min_bucket: { value: number | null; }; median_absolute_deviation: { value: number | null; }; moving_avg: { value: number | null; } | undefined; moving_fn: { value: number | null; }; moving_percentiles: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record | undefined; missing: { doc_count: number; } & SubAggregateOf; multi_terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string[]; } & SubAggregateOf)[]; }; nested: { doc_count: number; } & SubAggregateOf; normalize: { value: number | null; value_as_string?: string | undefined; }; parent: { doc_count: number; } & SubAggregateOf; percentiles: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentile_ranks: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentiles_bucket: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; range: MaybeKeyed; rare_terms: ({ key: string | number; doc_count: number; } & SubAggregateOf)[]; rate: { value: number | null; }; reverse_nested: { doc_count: number; } & SubAggregateOf; random_sampler: { seed: number; probability: number; doc_count: number; } & SubAggregateOf; sampler: { doc_count: number; } & SubAggregateOf; scripted_metric: { value: unknown; }; serial_diff: { value: number | null; value_as_string?: string | undefined; }; significant_terms: { doc_count: number; bg_count: number; buckets: ({ key: string | number; score: number; doc_count: number; bg_count: number; } & SubAggregateOf)[]; }; significant_text: { doc_count: number; buckets: { key: string; doc_count: number; score: number; bg_count: number; }[]; }; stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_as_string: string; }); stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; }; string_stats: { count: number; min_length: number | null; max_length: number | null; avg_length: number | null; entropy: number | null; distribution: Record; }; sum: { value: number | null; value_as_string?: string | undefined; }; sum_bucket: { value: number | null; }; terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string | number; key_as_string?: string | undefined; } & SubAggregateOf)[]; }; top_hits: { hits: { total: { value: number; relation: \"gte\" | \"eq\"; }; max_score: number | null; hits: TAggregationContainer extends { top_hits: ", + "AggregationsTopHitsAggregation", + "; } ? HitsOf : ", + "SearchHitsMetadata", + "; }; }; top_metrics: { top: { sort: string[] | number[]; metrics: Record, string | number | null>; }[]; }; weighted_avg: { value: number | null; }; value_count: { value: number; }; }, Exclude, \"aggs\" | \"aggregations\"> & string> extends readonly any[] ? (readonly any[] & Pick & { adjacency_matrix: { buckets: ({ key: string; doc_count: number; } & SubAggregateOf)[]; }; auto_date_histogram: { interval: string; buckets: ({ key: number; key_as_string: string; doc_count: number; } & SubAggregateOf)[]; }; avg: { value: number | null; value_as_string?: string | undefined; }; avg_bucket: { value: number | null; }; boxplot: { min: number | null; max: number | null; q1: number | null; q2: number | null; q3: number | null; }; bucket_correlation: { value: number | null; }; bucket_count_ks_test: { less: number; greater: number; two_sided: number; }; bucket_script: { value: unknown; }; cardinality: { value: number; }; children: { doc_count: number; } & SubAggregateOf; composite: { after_key: CompositeKeysOf; buckets: ({ doc_count: number; key: CompositeKeysOf; } & SubAggregateOf)[]; }; cumulative_cardinality: { value: number; }; cumulative_sum: { value: number; }; date_histogram: MaybeKeyed, string>; date_range: MaybeKeyed & Partial<{ to: string | number; to_as_string: string; }> & { doc_count: number; key: string; }, string>; derivative: { value: number | null; } | undefined; extended_stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_of_squares_as_string: string; variance_population_as_string: string; variance_sampling_as_string: string; std_deviation_as_string: string; std_deviation_population_as_string: string; std_deviation_sampling_as_string: string; std_deviation_bounds_as_string: { upper: string; lower: string; upper_population: string; lower_population: string; upper_sampling: string; lower_sampling: string; }; }); extended_stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number | null; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; }; filter: { doc_count: number; } & SubAggregateOf; filters: { buckets: TAggregationContainer extends { filters: { filters: any[]; }; } ? ({ doc_count: number; } & SubAggregateOf)[] : TAggregationContainer extends { filters: { filters: Record; }; } ? { [key in keyof TAggregationContainer[\"filters\"][\"filters\"]]: { doc_count: number; } & SubAggregateOf; } & (TAggregationContainer extends { filters: { other_bucket_key: infer TOtherBucketKey; }; } ? Record> : unknown) & (TAggregationContainer extends { filters: { other_bucket: true; }; } ? { _other: { doc_count: number; } & SubAggregateOf; } : unknown) : unknown; }; geo_bounds: { top_left: { lat: number | null; lon: number | null; }; bottom_right: { lat: number | null; lon: number | null; }; }; geo_centroid: { count: number; location: { lat: number; lon: number; }; }; geo_distance: MaybeKeyed, string>; geo_hash: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; geotile_grid: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; global: { doc_count: number; } & SubAggregateOf; histogram: MaybeKeyed, string>; ip_range: MaybeKeyed; inference: { value: number; prediction_probability: number; prediction_score: number; }; max: { value: number | null; value_as_string?: string | undefined; }; max_bucket: { value: number | null; }; min: { value: number | null; value_as_string?: string | undefined; }; min_bucket: { value: number | null; }; median_absolute_deviation: { value: number | null; }; moving_avg: { value: number | null; } | undefined; moving_fn: { value: number | null; }; moving_percentiles: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record | undefined; missing: { doc_count: number; } & SubAggregateOf; multi_terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string[]; } & SubAggregateOf)[]; }; nested: { doc_count: number; } & SubAggregateOf; normalize: { value: number | null; value_as_string?: string | undefined; }; parent: { doc_count: number; } & SubAggregateOf; percentiles: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentile_ranks: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentiles_bucket: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; range: MaybeKeyed; rare_terms: ({ key: string | number; doc_count: number; } & SubAggregateOf)[]; rate: { value: number | null; }; reverse_nested: { doc_count: number; } & SubAggregateOf; random_sampler: { seed: number; probability: number; doc_count: number; } & SubAggregateOf; sampler: { doc_count: number; } & SubAggregateOf; scripted_metric: { value: unknown; }; serial_diff: { value: number | null; value_as_string?: string | undefined; }; significant_terms: { doc_count: number; bg_count: number; buckets: ({ key: string | number; score: number; doc_count: number; bg_count: number; } & SubAggregateOf)[]; }; significant_text: { doc_count: number; buckets: { key: string; doc_count: number; score: number; bg_count: number; }[]; }; stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_as_string: string; }); stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; }; string_stats: { count: number; min_length: number | null; max_length: number | null; avg_length: number | null; entropy: number | null; distribution: Record; }; sum: { value: number | null; value_as_string?: string | undefined; }; sum_bucket: { value: number | null; }; terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string | number; key_as_string?: string | undefined; } & SubAggregateOf)[]; }; top_hits: { hits: { total: { value: number; relation: \"gte\" | \"eq\"; }; max_score: number | null; hits: TAggregationContainer extends { top_hits: ", + "AggregationsTopHitsAggregation", + "; } ? HitsOf : ", + "SearchHitsMetadata", + "; }; }; top_metrics: { top: { sort: string[] | number[]; metrics: Record, string | number | null>; }[]; }; weighted_avg: { value: number | null; }; value_count: { value: number; }; }, Exclude, \"aggs\" | \"aggregations\"> & string>)[number] : Pick & { adjacency_matrix: { buckets: ({ key: string; doc_count: number; } & SubAggregateOf)[]; }; auto_date_histogram: { interval: string; buckets: ({ key: number; key_as_string: string; doc_count: number; } & SubAggregateOf)[]; }; avg: { value: number | null; value_as_string?: string | undefined; }; avg_bucket: { value: number | null; }; boxplot: { min: number | null; max: number | null; q1: number | null; q2: number | null; q3: number | null; }; bucket_correlation: { value: number | null; }; bucket_count_ks_test: { less: number; greater: number; two_sided: number; }; bucket_script: { value: unknown; }; cardinality: { value: number; }; children: { doc_count: number; } & SubAggregateOf; composite: { after_key: CompositeKeysOf; buckets: ({ doc_count: number; key: CompositeKeysOf; } & SubAggregateOf)[]; }; cumulative_cardinality: { value: number; }; cumulative_sum: { value: number; }; date_histogram: MaybeKeyed, string>; date_range: MaybeKeyed & Partial<{ to: string | number; to_as_string: string; }> & { doc_count: number; key: string; }, string>; derivative: { value: number | null; } | undefined; extended_stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_of_squares_as_string: string; variance_population_as_string: string; variance_sampling_as_string: string; std_deviation_as_string: string; std_deviation_population_as_string: string; std_deviation_sampling_as_string: string; std_deviation_bounds_as_string: { upper: string; lower: string; upper_population: string; lower_population: string; upper_sampling: string; lower_sampling: string; }; }); extended_stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number | null; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; }; filter: { doc_count: number; } & SubAggregateOf; filters: { buckets: TAggregationContainer extends { filters: { filters: any[]; }; } ? ({ doc_count: number; } & SubAggregateOf)[] : TAggregationContainer extends { filters: { filters: Record; }; } ? { [key in keyof TAggregationContainer[\"filters\"][\"filters\"]]: { doc_count: number; } & SubAggregateOf; } & (TAggregationContainer extends { filters: { other_bucket_key: infer TOtherBucketKey; }; } ? Record> : unknown) & (TAggregationContainer extends { filters: { other_bucket: true; }; } ? { _other: { doc_count: number; } & SubAggregateOf; } : unknown) : unknown; }; geo_bounds: { top_left: { lat: number | null; lon: number | null; }; bottom_right: { lat: number | null; lon: number | null; }; }; geo_centroid: { count: number; location: { lat: number; lon: number; }; }; geo_distance: MaybeKeyed, string>; geo_hash: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; geotile_grid: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; global: { doc_count: number; } & SubAggregateOf; histogram: MaybeKeyed, string>; ip_range: MaybeKeyed; inference: { value: number; prediction_probability: number; prediction_score: number; }; max: { value: number | null; value_as_string?: string | undefined; }; max_bucket: { value: number | null; }; min: { value: number | null; value_as_string?: string | undefined; }; min_bucket: { value: number | null; }; median_absolute_deviation: { value: number | null; }; moving_avg: { value: number | null; } | undefined; moving_fn: { value: number | null; }; moving_percentiles: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record | undefined; missing: { doc_count: number; } & SubAggregateOf; multi_terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string[]; } & SubAggregateOf)[]; }; nested: { doc_count: number; } & SubAggregateOf; normalize: { value: number | null; value_as_string?: string | undefined; }; parent: { doc_count: number; } & SubAggregateOf; percentiles: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentile_ranks: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentiles_bucket: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; range: MaybeKeyed; rare_terms: ({ key: string | number; doc_count: number; } & SubAggregateOf)[]; rate: { value: number | null; }; reverse_nested: { doc_count: number; } & SubAggregateOf; random_sampler: { seed: number; probability: number; doc_count: number; } & SubAggregateOf; sampler: { doc_count: number; } & SubAggregateOf; scripted_metric: { value: unknown; }; serial_diff: { value: number | null; value_as_string?: string | undefined; }; significant_terms: { doc_count: number; bg_count: number; buckets: ({ key: string | number; score: number; doc_count: number; bg_count: number; } & SubAggregateOf)[]; }; significant_text: { doc_count: number; buckets: { key: string; doc_count: number; score: number; bg_count: number; }[]; }; stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_as_string: string; }); stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; }; string_stats: { count: number; min_length: number | null; max_length: number | null; avg_length: number | null; entropy: number | null; distribution: Record; }; sum: { value: number | null; value_as_string?: string | undefined; }; sum_bucket: { value: number | null; }; terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string | number; key_as_string?: string | undefined; } & SubAggregateOf)[]; }; top_hits: { hits: { total: { value: number; relation: \"gte\" | \"eq\"; }; max_score: number | null; hits: TAggregationContainer extends { top_hits: ", + "AggregationsTopHitsAggregation", + "; } ? HitsOf : ", + "SearchHitsMetadata", + "; }; }; top_metrics: { top: { sort: string[] | number[]; metrics: Record, string | number | null>; }[]; }; weighted_avg: { value: number | null; }; value_count: { value: number; }; }, Exclude, \"aggs\" | \"aggregations\"> & string> extends ArrayLike ? (ArrayLike & Pick & { adjacency_matrix: { buckets: ({ key: string; doc_count: number; } & SubAggregateOf)[]; }; auto_date_histogram: { interval: string; buckets: ({ key: number; key_as_string: string; doc_count: number; } & SubAggregateOf)[]; }; avg: { value: number | null; value_as_string?: string | undefined; }; avg_bucket: { value: number | null; }; boxplot: { min: number | null; max: number | null; q1: number | null; q2: number | null; q3: number | null; }; bucket_correlation: { value: number | null; }; bucket_count_ks_test: { less: number; greater: number; two_sided: number; }; bucket_script: { value: unknown; }; cardinality: { value: number; }; children: { doc_count: number; } & SubAggregateOf; composite: { after_key: CompositeKeysOf; buckets: ({ doc_count: number; key: CompositeKeysOf; } & SubAggregateOf)[]; }; cumulative_cardinality: { value: number; }; cumulative_sum: { value: number; }; date_histogram: MaybeKeyed, string>; date_range: MaybeKeyed & Partial<{ to: string | number; to_as_string: string; }> & { doc_count: number; key: string; }, string>; derivative: { value: number | null; } | undefined; extended_stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_of_squares_as_string: string; variance_population_as_string: string; variance_sampling_as_string: string; std_deviation_as_string: string; std_deviation_population_as_string: string; std_deviation_sampling_as_string: string; std_deviation_bounds_as_string: { upper: string; lower: string; upper_population: string; lower_population: string; upper_sampling: string; lower_sampling: string; }; }); extended_stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number | null; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; }; filter: { doc_count: number; } & SubAggregateOf; filters: { buckets: TAggregationContainer extends { filters: { filters: any[]; }; } ? ({ doc_count: number; } & SubAggregateOf)[] : TAggregationContainer extends { filters: { filters: Record; }; } ? { [key in keyof TAggregationContainer[\"filters\"][\"filters\"]]: { doc_count: number; } & SubAggregateOf; } & (TAggregationContainer extends { filters: { other_bucket_key: infer TOtherBucketKey; }; } ? Record> : unknown) & (TAggregationContainer extends { filters: { other_bucket: true; }; } ? { _other: { doc_count: number; } & SubAggregateOf; } : unknown) : unknown; }; geo_bounds: { top_left: { lat: number | null; lon: number | null; }; bottom_right: { lat: number | null; lon: number | null; }; }; geo_centroid: { count: number; location: { lat: number; lon: number; }; }; geo_distance: MaybeKeyed, string>; geo_hash: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; geotile_grid: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; global: { doc_count: number; } & SubAggregateOf; histogram: MaybeKeyed, string>; ip_range: MaybeKeyed; inference: { value: number; prediction_probability: number; prediction_score: number; }; max: { value: number | null; value_as_string?: string | undefined; }; max_bucket: { value: number | null; }; min: { value: number | null; value_as_string?: string | undefined; }; min_bucket: { value: number | null; }; median_absolute_deviation: { value: number | null; }; moving_avg: { value: number | null; } | undefined; moving_fn: { value: number | null; }; moving_percentiles: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record | undefined; missing: { doc_count: number; } & SubAggregateOf; multi_terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string[]; } & SubAggregateOf)[]; }; nested: { doc_count: number; } & SubAggregateOf; normalize: { value: number | null; value_as_string?: string | undefined; }; parent: { doc_count: number; } & SubAggregateOf; percentiles: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentile_ranks: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentiles_bucket: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; range: MaybeKeyed; rare_terms: ({ key: string | number; doc_count: number; } & SubAggregateOf)[]; rate: { value: number | null; }; reverse_nested: { doc_count: number; } & SubAggregateOf; random_sampler: { seed: number; probability: number; doc_count: number; } & SubAggregateOf; sampler: { doc_count: number; } & SubAggregateOf; scripted_metric: { value: unknown; }; serial_diff: { value: number | null; value_as_string?: string | undefined; }; significant_terms: { doc_count: number; bg_count: number; buckets: ({ key: string | number; score: number; doc_count: number; bg_count: number; } & SubAggregateOf)[]; }; significant_text: { doc_count: number; buckets: { key: string; doc_count: number; score: number; bg_count: number; }[]; }; stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_as_string: string; }); stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; }; string_stats: { count: number; min_length: number | null; max_length: number | null; avg_length: number | null; entropy: number | null; distribution: Record; }; sum: { value: number | null; value_as_string?: string | undefined; }; sum_bucket: { value: number | null; }; terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string | number; key_as_string?: string | undefined; } & SubAggregateOf)[]; }; top_hits: { hits: { total: { value: number; relation: \"gte\" | \"eq\"; }; max_score: number | null; hits: TAggregationContainer extends { top_hits: ", + "AggregationsTopHitsAggregation", + "; } ? HitsOf : ", + "SearchHitsMetadata", + "; }; }; top_metrics: { top: { sort: string[] | number[]; metrics: Record, string | number | null>; }[]; }; weighted_avg: { value: number | null; }; value_count: { value: number; }; }, Exclude, \"aggs\" | \"aggregations\"> & string>)[number] : Pick & { adjacency_matrix: { buckets: ({ key: string; doc_count: number; } & SubAggregateOf)[]; }; auto_date_histogram: { interval: string; buckets: ({ key: number; key_as_string: string; doc_count: number; } & SubAggregateOf)[]; }; avg: { value: number | null; value_as_string?: string | undefined; }; avg_bucket: { value: number | null; }; boxplot: { min: number | null; max: number | null; q1: number | null; q2: number | null; q3: number | null; }; bucket_correlation: { value: number | null; }; bucket_count_ks_test: { less: number; greater: number; two_sided: number; }; bucket_script: { value: unknown; }; cardinality: { value: number; }; children: { doc_count: number; } & SubAggregateOf; composite: { after_key: CompositeKeysOf; buckets: ({ doc_count: number; key: CompositeKeysOf; } & SubAggregateOf)[]; }; cumulative_cardinality: { value: number; }; cumulative_sum: { value: number; }; date_histogram: MaybeKeyed, string>; date_range: MaybeKeyed & Partial<{ to: string | number; to_as_string: string; }> & { doc_count: number; key: string; }, string>; derivative: { value: number | null; } | undefined; extended_stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_of_squares_as_string: string; variance_population_as_string: string; variance_sampling_as_string: string; std_deviation_as_string: string; std_deviation_population_as_string: string; std_deviation_sampling_as_string: string; std_deviation_bounds_as_string: { upper: string; lower: string; upper_population: string; lower_population: string; upper_sampling: string; lower_sampling: string; }; }); extended_stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number | null; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; }; filter: { doc_count: number; } & SubAggregateOf; filters: { buckets: TAggregationContainer extends { filters: { filters: any[]; }; } ? ({ doc_count: number; } & SubAggregateOf)[] : TAggregationContainer extends { filters: { filters: Record; }; } ? { [key in keyof TAggregationContainer[\"filters\"][\"filters\"]]: { doc_count: number; } & SubAggregateOf; } & (TAggregationContainer extends { filters: { other_bucket_key: infer TOtherBucketKey; }; } ? Record> : unknown) & (TAggregationContainer extends { filters: { other_bucket: true; }; } ? { _other: { doc_count: number; } & SubAggregateOf; } : unknown) : unknown; }; geo_bounds: { top_left: { lat: number | null; lon: number | null; }; bottom_right: { lat: number | null; lon: number | null; }; }; geo_centroid: { count: number; location: { lat: number; lon: number; }; }; geo_distance: MaybeKeyed, string>; geo_hash: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; geotile_grid: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; global: { doc_count: number; } & SubAggregateOf; histogram: MaybeKeyed, string>; ip_range: MaybeKeyed; inference: { value: number; prediction_probability: number; prediction_score: number; }; max: { value: number | null; value_as_string?: string | undefined; }; max_bucket: { value: number | null; }; min: { value: number | null; value_as_string?: string | undefined; }; min_bucket: { value: number | null; }; median_absolute_deviation: { value: number | null; }; moving_avg: { value: number | null; } | undefined; moving_fn: { value: number | null; }; moving_percentiles: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record | undefined; missing: { doc_count: number; } & SubAggregateOf; multi_terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string[]; } & SubAggregateOf)[]; }; nested: { doc_count: number; } & SubAggregateOf; normalize: { value: number | null; value_as_string?: string | undefined; }; parent: { doc_count: number; } & SubAggregateOf; percentiles: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentile_ranks: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentiles_bucket: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; range: MaybeKeyed; rare_terms: ({ key: string | number; doc_count: number; } & SubAggregateOf)[]; rate: { value: number | null; }; reverse_nested: { doc_count: number; } & SubAggregateOf; random_sampler: { seed: number; probability: number; doc_count: number; } & SubAggregateOf; sampler: { doc_count: number; } & SubAggregateOf; scripted_metric: { value: unknown; }; serial_diff: { value: number | null; value_as_string?: string | undefined; }; significant_terms: { doc_count: number; bg_count: number; buckets: ({ key: string | number; score: number; doc_count: number; bg_count: number; } & SubAggregateOf)[]; }; significant_text: { doc_count: number; buckets: { key: string; doc_count: number; score: number; bg_count: number; }[]; }; stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_as_string: string; }); stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; }; string_stats: { count: number; min_length: number | null; max_length: number | null; avg_length: number | null; entropy: number | null; distribution: Record; }; sum: { value: number | null; value_as_string?: string | undefined; }; sum_bucket: { value: number | null; }; terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string | number; key_as_string?: string | undefined; } & SubAggregateOf)[]; }; top_hits: { hits: { total: { value: number; relation: \"gte\" | \"eq\"; }; max_score: number | null; hits: TAggregationContainer extends { top_hits: ", + "AggregationsTopHitsAggregation", + "; } ? HitsOf : ", + "SearchHitsMetadata", + "; }; }; top_metrics: { top: { sort: string[] | number[]; metrics: Record, string | number | null>; }[]; }; weighted_avg: { value: number | null; }; value_count: { value: number; }; }, Exclude, \"aggs\" | \"aggregations\"> & string> extends object ? Pick & { adjacency_matrix: { buckets: ({ key: string; doc_count: number; } & SubAggregateOf)[]; }; auto_date_histogram: { interval: string; buckets: ({ key: number; key_as_string: string; doc_count: number; } & SubAggregateOf)[]; }; avg: { value: number | null; value_as_string?: string | undefined; }; avg_bucket: { value: number | null; }; boxplot: { min: number | null; max: number | null; q1: number | null; q2: number | null; q3: number | null; }; bucket_correlation: { value: number | null; }; bucket_count_ks_test: { less: number; greater: number; two_sided: number; }; bucket_script: { value: unknown; }; cardinality: { value: number; }; children: { doc_count: number; } & SubAggregateOf; composite: { after_key: CompositeKeysOf; buckets: ({ doc_count: number; key: CompositeKeysOf; } & SubAggregateOf)[]; }; cumulative_cardinality: { value: number; }; cumulative_sum: { value: number; }; date_histogram: MaybeKeyed, string>; date_range: MaybeKeyed & Partial<{ to: string | number; to_as_string: string; }> & { doc_count: number; key: string; }, string>; derivative: { value: number | null; } | undefined; extended_stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_of_squares_as_string: string; variance_population_as_string: string; variance_sampling_as_string: string; std_deviation_as_string: string; std_deviation_population_as_string: string; std_deviation_sampling_as_string: string; std_deviation_bounds_as_string: { upper: string; lower: string; upper_population: string; lower_population: string; upper_sampling: string; lower_sampling: string; }; }); extended_stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number | null; sum_of_squares: number | null; variance: number | null; variance_population: number | null; variance_sampling: number | null; std_deviation: number | null; std_deviation_population: number | null; std_deviation_sampling: number | null; std_deviation_bounds: { upper: number | null; lower: number | null; upper_population: number | null; lower_population: number | null; upper_sampling: number | null; lower_sampling: number | null; }; }; filter: { doc_count: number; } & SubAggregateOf; filters: { buckets: TAggregationContainer extends { filters: { filters: any[]; }; } ? ({ doc_count: number; } & SubAggregateOf)[] : TAggregationContainer extends { filters: { filters: Record; }; } ? { [key in keyof TAggregationContainer[\"filters\"][\"filters\"]]: { doc_count: number; } & SubAggregateOf; } & (TAggregationContainer extends { filters: { other_bucket_key: infer TOtherBucketKey; }; } ? Record> : unknown) & (TAggregationContainer extends { filters: { other_bucket: true; }; } ? { _other: { doc_count: number; } & SubAggregateOf; } : unknown) : unknown; }; geo_bounds: { top_left: { lat: number | null; lon: number | null; }; bottom_right: { lat: number | null; lon: number | null; }; }; geo_centroid: { count: number; location: { lat: number; lon: number; }; }; geo_distance: MaybeKeyed, string>; geo_hash: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; geotile_grid: { buckets: ({ doc_count: number; key: string; } & SubAggregateOf)[]; }; global: { doc_count: number; } & SubAggregateOf; histogram: MaybeKeyed, string>; ip_range: MaybeKeyed; inference: { value: number; prediction_probability: number; prediction_score: number; }; max: { value: number | null; value_as_string?: string | undefined; }; max_bucket: { value: number | null; }; min: { value: number | null; value_as_string?: string | undefined; }; min_bucket: { value: number | null; }; median_absolute_deviation: { value: number | null; }; moving_avg: { value: number | null; } | undefined; moving_fn: { value: number | null; }; moving_percentiles: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record | undefined; missing: { doc_count: number; } & SubAggregateOf; multi_terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string[]; } & SubAggregateOf)[]; }; nested: { doc_count: number; } & SubAggregateOf; normalize: { value: number | null; value_as_string?: string | undefined; }; parent: { doc_count: number; } & SubAggregateOf; percentiles: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentile_ranks: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; percentiles_bucket: { values: TAggregationContainer extends Record ? { key: number; value: number | null; }[] : Record; }; range: MaybeKeyed; rare_terms: ({ key: string | number; doc_count: number; } & SubAggregateOf)[]; rate: { value: number | null; }; reverse_nested: { doc_count: number; } & SubAggregateOf; random_sampler: { seed: number; probability: number; doc_count: number; } & SubAggregateOf; sampler: { doc_count: number; } & SubAggregateOf; scripted_metric: { value: unknown; }; serial_diff: { value: number | null; value_as_string?: string | undefined; }; significant_terms: { doc_count: number; bg_count: number; buckets: ({ key: string | number; score: number; doc_count: number; bg_count: number; } & SubAggregateOf)[]; }; significant_text: { doc_count: number; buckets: { key: string; doc_count: number; score: number; bg_count: number; }[]; }; stats: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; } & ({} | { min_as_string: string; max_as_string: string; avg_as_string: string; sum_as_string: string; }); stats_bucket: { count: number; min: number | null; max: number | null; avg: number | null; sum: number; }; string_stats: { count: number; min_length: number | null; max_length: number | null; avg_length: number | null; entropy: number | null; distribution: Record; }; sum: { value: number | null; value_as_string?: string | undefined; }; sum_bucket: { value: number | null; }; terms: { doc_count_error_upper_bound: number; sum_other_doc_count: number; buckets: ({ doc_count: number; key: string | number; key_as_string?: string | undefined; } & SubAggregateOf)[]; }; top_hits: { hits: { total: { value: number; relation: \"gte\" | \"eq\"; }; max_score: number | null; hits: TAggregationContainer extends { top_hits: ", + "AggregationsTopHitsAggregation", + "; } ? HitsOf : ", + "SearchHitsMetadata", + "; }; }; top_metrics: { top: { sort: string[] | number[]; metrics: Record, string | number | null>; }[]; }; weighted_avg: { value: number | null; }; value_count: { value: number; }; }, Exclude, \"aggs\" | \"aggregations\"> & string>[Exclude, \"aggs\" | \"aggregations\"> & string] : never" + ], + "path": "packages/kbn-es-types/src/search.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.AggregationOptionsByType", + "type": "Type", + "tags": [], + "label": "AggregationOptionsByType", + "description": [], + "signature": [ + "{ aggregations: Record; aggs: Record; meta: ", + "Metadata", + "; adjacency_matrix: ", + "AggregationsAdjacencyMatrixAggregation", + "; auto_date_histogram: ", + "AggregationsAutoDateHistogramAggregation", + "; avg: ", + "AggregationsAverageAggregation", + "; avg_bucket: ", + "AggregationsAverageBucketAggregation", + "; boxplot: ", + "AggregationsBoxplotAggregation", + "; bucket_script: ", + "AggregationsBucketScriptAggregation", + "; bucket_selector: ", + "AggregationsBucketSelectorAggregation", + "; bucket_sort: ", + "AggregationsBucketSortAggregation", + "; bucket_count_ks_test: ", + "AggregationsBucketKsAggregation", + "; bucket_correlation: ", + "AggregationsBucketCorrelationAggregation", + "; cardinality: ", + "AggregationsCardinalityAggregation", + "; categorize_text: ", + "AggregationsCategorizeTextAggregation", + "; children: ", + "AggregationsChildrenAggregation", + "; composite: ", + "AggregationsCompositeAggregation", + "; cumulative_cardinality: ", + "AggregationsCumulativeCardinalityAggregation", + "; cumulative_sum: ", + "AggregationsCumulativeSumAggregation", + "; date_histogram: ", + "AggregationsDateHistogramAggregation", + "; date_range: ", + "AggregationsDateRangeAggregation", + "; derivative: ", + "AggregationsDerivativeAggregation", + "; diversified_sampler: ", + "AggregationsDiversifiedSamplerAggregation", + "; extended_stats: ", + "AggregationsExtendedStatsAggregation", + "; extended_stats_bucket: ", + "AggregationsExtendedStatsBucketAggregation", + "; filter: ", + "QueryDslQueryContainer", + "; filters: ", + "AggregationsFiltersAggregation", + "; geo_bounds: ", + "AggregationsGeoBoundsAggregation", + "; geo_centroid: ", + "AggregationsGeoCentroidAggregation", + "; geo_distance: ", + "AggregationsGeoDistanceAggregation", + "; geohash_grid: ", + "AggregationsGeoHashGridAggregation", + "; geo_line: ", + "AggregationsGeoLineAggregation", + "; geotile_grid: ", + "AggregationsGeoTileGridAggregation", + "; geohex_grid: ", + "AggregationsGeohexGridAggregation", + "; global: ", + "AggregationsGlobalAggregation", + "; histogram: ", + "AggregationsHistogramAggregation", + "; ip_range: ", + "AggregationsIpRangeAggregation", + "; inference: ", + "AggregationsInferenceAggregation", + "; line: ", + "AggregationsGeoLineAggregation", + "; matrix_stats: ", + "AggregationsMatrixStatsAggregation", + "; max: ", + "AggregationsMaxAggregation", + "; max_bucket: ", + "AggregationsMaxBucketAggregation", + "; median_absolute_deviation: ", + "AggregationsMedianAbsoluteDeviationAggregation", + "; min: ", + "AggregationsMinAggregation", + "; min_bucket: ", + "AggregationsMinBucketAggregation", + "; missing: ", + "AggregationsMissingAggregation", + "; moving_avg: ", + "AggregationsMovingAverageAggregation", + "; moving_percentiles: ", + "AggregationsMovingPercentilesAggregation", + "; moving_fn: ", + "AggregationsMovingFunctionAggregation", + "; multi_terms: ", + "AggregationsMultiTermsAggregation", + "; nested: ", + "AggregationsNestedAggregation", + "; normalize: ", + "AggregationsNormalizeAggregation", + "; parent: ", + "AggregationsParentAggregation", + "; percentile_ranks: ", + "AggregationsPercentileRanksAggregation", + "; percentiles: ", + "AggregationsPercentilesAggregation", + "; percentiles_bucket: ", + "AggregationsPercentilesBucketAggregation", + "; range: ", + "AggregationsRangeAggregation", + "; rare_terms: ", + "AggregationsRareTermsAggregation", + "; rate: ", + "AggregationsRateAggregation", + "; reverse_nested: ", + "AggregationsReverseNestedAggregation", + "; sampler: ", + "AggregationsSamplerAggregation", + "; scripted_metric: ", + "AggregationsScriptedMetricAggregation", + "; serial_diff: ", + "AggregationsSerialDifferencingAggregation", + "; significant_terms: ", + "AggregationsSignificantTermsAggregation", + "; significant_text: ", + "AggregationsSignificantTextAggregation", + "; stats: ", + "AggregationsStatsAggregation", + "; stats_bucket: ", + "AggregationsStatsBucketAggregation", + "; string_stats: ", + "AggregationsStringStatsAggregation", + "; sum: ", + "AggregationsSumAggregation", + "; sum_bucket: ", + "AggregationsSumBucketAggregation", + "; terms: ", + "AggregationsTermsAggregation", + "; top_hits: ", + "AggregationsTopHitsAggregation", + "; t_test: ", + "AggregationsTTestAggregation", + "; top_metrics: ", + "AggregationsTopMetricsAggregation", + "; value_count: ", + "AggregationsValueCountAggregation", + "; weighted_avg: ", + "AggregationsWeightedAverageAggregation", + "; variable_width_histogram: ", + "AggregationsVariableWidthHistogramAggregation", + "; }" + ], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.ESFilter", + "type": "Type", + "tags": [], + "label": "ESFilter", + "description": [], + "signature": [ + "QueryDslQueryContainer" + ], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.ESSearchRequest", + "type": "Type", + "tags": [], + "label": "ESSearchRequest", + "description": [], + "signature": [ + "SearchRequest" + ], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.ESSearchResponse", + "type": "Type", + "tags": [], + "label": "ESSearchResponse", + "description": [], + "signature": [ + "Omit<", + "SearchResponse", + ">, \"hits\" | \"aggregations\"> & (TSearchRequest[\"body\"] extends TopLevelAggregationRequest ? WrapAggregationResponse> : TSearchRequest extends TopLevelAggregationRequest ? WrapAggregationResponse> : { aggregations?: unknown; }) & { hits: Omit<", + "SearchHitsMetadata", + ", \"hits\" | \"total\"> & (TOptions[\"restTotalHitsAsInt\"] extends true ? { total: number; } : { total: { value: number; relation: \"gte\" | \"eq\"; }; }) & { hits: HitsOf | undefined; aggs?: Record | undefined; collapse?: ", + "SearchFieldCollapse", + " | undefined; explain?: boolean | undefined; from?: number | undefined; highlight?: ", + "SearchHighlight", + " | undefined; track_total_hits?: ", + "SearchTrackHits", + " | undefined; indices_boost?: Record[] | undefined; docvalue_fields?: (string | ", + "QueryDslFieldAndFormat", + ")[] | undefined; min_score?: number | undefined; post_filter?: ", + "QueryDslQueryContainer", + " | undefined; profile?: boolean | undefined; query?: ", + "QueryDslQueryContainer", + " | undefined; rescore?: ", + "SearchRescore", + " | ", + "SearchRescore", + "[] | undefined; script_fields?: Record | undefined; search_after?: ", + "SortResults", + " | undefined; size?: number | undefined; slice?: ", + "SlicedScroll", + " | undefined; sort?: ", + "Sort", + " | undefined; _source?: ", + "SearchSourceConfig", + " | undefined; fields?: (string | ", + "QueryDslFieldAndFormat", + ")[] | undefined; suggest?: ", + "SearchSuggester", + " | undefined; terminate_after?: number | undefined; timeout?: string | undefined; track_scores?: boolean | undefined; version?: boolean | undefined; seq_no_primary_term?: boolean | undefined; stored_fields?: ", + "Fields", + " | undefined; pit?: ", + "SearchPointInTimeReference", + " | undefined; runtime_mappings?: ", + "MappingRuntimeFields", + " | undefined; stats?: string[] | undefined; } | undefined ? TSearchRequest[\"body\"] : TSearchRequest, TDocument>; }; }" + ], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.ESSourceOptions", + "type": "Type", + "tags": [], + "label": "ESSourceOptions", + "description": [], + "signature": [ + "string | boolean | string[]" + ], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.InferSearchResponseOf", + "type": "Type", + "tags": [], + "label": "InferSearchResponseOf", + "description": [], + "signature": [ + "Omit<", + "SearchResponse", + ">, \"hits\" | \"aggregations\"> & (TSearchRequest[\"body\"] extends TopLevelAggregationRequest ? WrapAggregationResponse> : TSearchRequest extends TopLevelAggregationRequest ? WrapAggregationResponse> : { aggregations?: unknown; }) & { hits: Omit<", + "SearchHitsMetadata", + ", \"hits\" | \"total\"> & (TOptions[\"restTotalHitsAsInt\"] extends true ? { total: number; } : { total: { value: number; relation: \"gte\" | \"eq\"; }; }) & { hits: HitsOf | undefined; aggs?: Record | undefined; collapse?: ", + "SearchFieldCollapse", + " | undefined; explain?: boolean | undefined; from?: number | undefined; highlight?: ", + "SearchHighlight", + " | undefined; track_total_hits?: ", + "SearchTrackHits", + " | undefined; indices_boost?: Record[] | undefined; docvalue_fields?: (string | ", + "QueryDslFieldAndFormat", + ")[] | undefined; min_score?: number | undefined; post_filter?: ", + "QueryDslQueryContainer", + " | undefined; profile?: boolean | undefined; query?: ", + "QueryDslQueryContainer", + " | undefined; rescore?: ", + "SearchRescore", + " | ", + "SearchRescore", + "[] | undefined; script_fields?: Record | undefined; search_after?: ", + "SortResults", + " | undefined; size?: number | undefined; slice?: ", + "SlicedScroll", + " | undefined; sort?: ", + "Sort", + " | undefined; _source?: ", + "SearchSourceConfig", + " | undefined; fields?: (string | ", + "QueryDslFieldAndFormat", + ")[] | undefined; suggest?: ", + "SearchSuggester", + " | undefined; terminate_after?: number | undefined; timeout?: string | undefined; track_scores?: boolean | undefined; version?: boolean | undefined; seq_no_primary_term?: boolean | undefined; stored_fields?: ", + "Fields", + " | undefined; pit?: ", + "SearchPointInTimeReference", + " | undefined; runtime_mappings?: ", + "MappingRuntimeFields", + " | undefined; stats?: string[] | undefined; } | undefined ? TSearchRequest[\"body\"] : TSearchRequest, TDocument>; }; }" + ], + "path": "packages/kbn-es-types/src/search.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.MaybeReadonlyArray", + "type": "Type", + "tags": [], + "label": "MaybeReadonlyArray", + "description": [], + "signature": [ + "T[] | readonly T[]" + ], + "path": "packages/kbn-es-types/src/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-server.SearchHit", + "type": "Type", + "tags": [], + "label": "SearchHit", + "description": [], + "signature": [ + "Omit<", + "SearchHit", + ", \"fields\" | \"_source\"> & (TSource extends false ? {} : { _source: TSource; }) & (TFields extends (string | ", + "QueryDslFieldAndFormat", + ")[] ? { fields: Partial, unknown[]>>; } : {}) & (TDocValueFields extends DocValueFields ? { fields: Partial, unknown[]>>; } : {})" + ], + "path": "packages/kbn-es-types/src/search.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx new file mode 100644 index 0000000000000..95466ada26028 --- /dev/null +++ b/api_docs/kbn_es_types.mdx @@ -0,0 +1,33 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnEsTypesPluginApi +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: 2022-09-21 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] +--- +import kbnEsTypesObj from './kbn_es_types.devdocs.json'; + + + +Contact Kibana Core for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 11 | 0 | 11 | 0 | + +## Server + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index c555fe8b7d5a5..7f2a5f8ffbca4 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 0e498ea0e9b54..94177dc5aa243 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: 2022-09-20 +date: 2022-09-21 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 eaeb3333485b0..44625438cd032 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: 2022-09-20 +date: 2022-09-21 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_generate.mdx b/api_docs/kbn_generate.mdx index 3bcaf385b30d3..af968a0d6c12b 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index 32da58c287d17..eb3041437f858 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index b619dcc8fce29..ea945e927f03b 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: 2022-09-20 +date: 2022-09-21 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 6010e62895745..5d79694335b6b 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 63fa535614bb5..94506cf8d9909 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: 2022-09-20 +date: 2022-09-21 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 73678fded69f2..0d4b974929b83 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: 2022-09-20 +date: 2022-09-21 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 6a2be69a99536..bf4c70817d7bc 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 55418c0839d6d..d051acb699996 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index dcd0bbfddac67..7d0955caeb361 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 2b192f2ae841e..b6c9a79910594 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index dfe4988fde861..4ed4996625614 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 61d0fe628c129..e1edaaac04cc2 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 7c2d9e7844a11..b8e4bbc6d85d7 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: 2022-09-20 +date: 2022-09-21 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 355064817f4d6..cdf7e9493bfde 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: 2022-09-20 +date: 2022-09-21 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 99845433826f3..3f07937de52fe 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: 2022-09-20 +date: 2022-09-21 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 6780c1f696b69..bc63c5e56f04c 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.devdocs.json b/api_docs/kbn_ml_agg_utils.devdocs.json index ced4750717a78..6c021a7a5bc78 100644 --- a/api_docs/kbn_ml_agg_utils.devdocs.json +++ b/api_docs/kbn_ml_agg_utils.devdocs.json @@ -637,6 +637,17 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.ChangePointGroup.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/packages/ml/agg_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/ml-agg-utils", "id": "def-server.ChangePointGroup.group", @@ -661,6 +672,89 @@ "path": "x-pack/packages/ml/agg_utils/src/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.ChangePointGroup.pValue", + "type": "CompoundType", + "tags": [], + "label": "pValue", + "description": [], + "signature": [ + "number | null" + ], + "path": "x-pack/packages/ml/agg_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.ChangePointGroup.histogram", + "type": "Array", + "tags": [], + "label": "histogram", + "description": [], + "signature": [ + { + "pluginId": "@kbn/ml-agg-utils", + "scope": "server", + "docId": "kibKbnMlAggUtilsPluginApi", + "section": "def-server.ChangePointHistogramItem", + "text": "ChangePointHistogramItem" + }, + "[] | undefined" + ], + "path": "x-pack/packages/ml/agg_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.ChangePointGroupHistogram", + "type": "Interface", + "tags": [], + "label": "ChangePointGroupHistogram", + "description": [ + "\nChange point histogram data for a group of field/value pairs." + ], + "path": "x-pack/packages/ml/agg_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.ChangePointGroupHistogram.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/packages/ml/agg_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.ChangePointGroupHistogram.histogram", + "type": "Array", + "tags": [], + "label": "histogram", + "description": [], + "signature": [ + { + "pluginId": "@kbn/ml-agg-utils", + "scope": "server", + "docId": "kibKbnMlAggUtilsPluginApi", + "section": "def-server.ChangePointHistogramItem", + "text": "ChangePointHistogramItem" + }, + "[]" + ], + "path": "x-pack/packages/ml/agg_utils/src/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index adadb5a8d1141..20d206ee85420 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact Machine Learning UI for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 58 | 2 | 39 | 3 | +| 64 | 2 | 44 | 3 | ## Server diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 1bd52ce9c5bc8..f03e2c0dd1368 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: 2022-09-20 +date: 2022-09-21 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_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index 372c7969c3806..f5c6ec4dab20c 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 902578461f024..4a2b7d251d645 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index cbc5ae1b1ded5..9dec2e2d12388 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: 2022-09-20 +date: 2022-09-21 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 42c37c78b5178..3ecb10b8ce84a 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 44d6ca0550963..629055ccc04e7 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: 2022-09-20 +date: 2022-09-21 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 4798bfbf8987a..f2e631ec8cd4b 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: 2022-09-20 +date: 2022-09-21 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 b9be224e32a5b..b7141c78f3cf9 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 40fa48fd2b023..5a9f1942a5bd6 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 1509876385b1f..0e6aab2d83377 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 0e8c7c73e7c84..c4061ab88aac1 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 6e19f121fd9ad..fd9731c4d32f5 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 2ffb661273b81..ec574df2ac420 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: 2022-09-20 +date: 2022-09-21 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_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 7e05e5af14825..060150aec0633 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: 2022-09-20 +date: 2022-09-21 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 d94c62d645fd5..1c47b09302c0e 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: 2022-09-20 +date: 2022-09-21 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 63986072c7322..343773fc6961f 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: 2022-09-20 +date: 2022-09-21 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 7a0b917859a62..5b6f8c7121eb2 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: 2022-09-20 +date: 2022-09-21 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 6177ab6c92c8d..d91fd25457476 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: 2022-09-20 +date: 2022-09-21 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 4b880041473c4..47970932a1793 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: 2022-09-20 +date: 2022-09-21 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 28cf4efef38a8..34e695f21aeea 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: 2022-09-20 +date: 2022-09-21 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 e2232050612c1..e58504680e2cf 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: 2022-09-20 +date: 2022-09-21 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 44b7742d2b5c7..a87cfd6fe0973 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: 2022-09-20 +date: 2022-09-21 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 b979309b06fc5..ff535c6f560d9 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: 2022-09-20 +date: 2022-09-21 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 fd74c70883973..5df5c3218e6a1 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: 2022-09-20 +date: 2022-09-21 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 0acf0fc188b95..fc58053025b36 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: 2022-09-20 +date: 2022-09-21 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 be7aff880057c..1af486fce1c5e 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: 2022-09-20 +date: 2022-09-21 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 bdba63997b786..b743139813871 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 5cf5c679becea..78782a2742f93 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: 2022-09-20 +date: 2022-09-21 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_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 8032ad63fef85..9d1ce452077a0 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: 2022-09-20 +date: 2022-09-21 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_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 50578bc364b66..86f562d4bb410 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: 2022-09-20 +date: 2022-09-21 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 453fd4a07cd2c..534731ed2ed6c 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: 2022-09-20 +date: 2022-09-21 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.devdocs.json b/api_docs/kbn_shared_ux_card_no_data.devdocs.json index a97e211368c5c..c1e08d1b9a31f 100644 --- a/api_docs/kbn_shared_ux_card_no_data.devdocs.json +++ b/api_docs/kbn_shared_ux_card_no_data.devdocs.json @@ -186,7 +186,11 @@ "signature": [ "{ children?: React.ReactNode; description?: React.ReactNode; category?: string | undefined; onError?: React.ReactEventHandler | undefined; hidden?: boolean | undefined; icon?: React.ReactElement<", "EuiIconProps", - ", string | React.JSXElementConstructor> | null | undefined; id?: string | undefined; image?: string | React.ReactElement> | undefined; className?: string | undefined; title?: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | undefined; onChange?: React.FormEventHandler | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; onClick?: React.MouseEventHandler | undefined; security?: string | undefined; defaultValue?: string | number | readonly string[] | undefined; lang?: string | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; role?: React.AriaRole | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"email\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: Booleanish | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: Booleanish | undefined; 'aria-checked'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"time\" | \"page\" | \"false\" | \"true\" | \"step\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: Booleanish | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: Booleanish | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: Booleanish | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"false\" | \"true\" | \"dialog\" | \"listbox\" | \"tree\" | undefined; 'aria-hidden'?: Booleanish | undefined; 'aria-invalid'?: boolean | \"false\" | \"true\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: Booleanish | undefined; 'aria-multiline'?: Booleanish | undefined; 'aria-multiselectable'?: Booleanish | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-readonly'?: Booleanish | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: Booleanish | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: Booleanish | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"other\" | \"ascending\" | \"descending\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; href?: string | undefined; rel?: string | undefined; target?: string | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"xs\" | \"l\" | \"xl\" | undefined; button?: React.ReactNode; footer?: React.ReactNode; hasBorder?: boolean | undefined; textAlign?: CardAlignment | undefined; titleElement?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"span\" | undefined; titleSize?: \"s\" | \"xs\" | undefined; betaBadgeProps?: Partial<(", + ", string | React.JSXElementConstructor> | null | undefined; id?: string | undefined; image?: string | React.ReactElement> | undefined; className?: string | undefined; title?: boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | undefined; onChange?: React.FormEventHandler | undefined; onKeyDown?: React.KeyboardEventHandler | undefined; onClick?: React.MouseEventHandler | undefined; security?: string | undefined; defaultValue?: string | number | readonly string[] | undefined; lang?: string | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; role?: React.AriaRole | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"email\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: Booleanish | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: Booleanish | undefined; 'aria-checked'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"time\" | \"page\" | \"false\" | \"true\" | \"step\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: Booleanish | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: Booleanish | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: Booleanish | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"false\" | \"true\" | \"dialog\" | \"listbox\" | \"tree\" | undefined; 'aria-hidden'?: Booleanish | undefined; 'aria-invalid'?: boolean | \"false\" | \"true\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: Booleanish | undefined; 'aria-multiline'?: Booleanish | undefined; 'aria-multiselectable'?: Booleanish | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-readonly'?: Booleanish | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: Booleanish | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: Booleanish | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"other\" | \"ascending\" | \"descending\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; css?: ", + "Interpolation", + "<", + "Theme", + ">; href?: string | undefined; rel?: string | undefined; target?: string | undefined; paddingSize?: \"none\" | \"m\" | \"s\" | \"xs\" | \"l\" | \"xl\" | undefined; button?: React.ReactNode; footer?: React.ReactNode; hasBorder?: boolean | undefined; textAlign?: CardAlignment | undefined; titleElement?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"span\" | undefined; titleSize?: \"s\" | \"xs\" | undefined; betaBadgeProps?: Partial<(", "CommonProps", " & ", "DisambiguateSet", diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 8f8e2cb2d0840..3b9307fe75198 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: 2022-09-20 +date: 2022-09-21 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 6b5cf577d2f23..d8a57acd59459 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: 2022-09-20 +date: 2022-09-21 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_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index ad46fe9c6337f..29650e5ed8646 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: 2022-09-20 +date: 2022-09-21 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_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 650f6b6de6657..9962da3b57786 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: 2022-09-20 +date: 2022-09-21 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 c526e3b3d7f6d..f5e9eec99917c 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: 2022-09-20 +date: 2022-09-21 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 620084197a3fc..2123307bc9e97 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: 2022-09-20 +date: 2022-09-21 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 53fe5c2b52348..e09c5179542e1 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: 2022-09-20 +date: 2022-09-21 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 1cc01f097e1f5..17b290a187bd0 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: 2022-09-20 +date: 2022-09-21 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 294ae75484592..0624865a7cb3e 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: 2022-09-20 +date: 2022-09-21 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 e228084b30143..5a3f2d93ec15d 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: 2022-09-20 +date: 2022-09-21 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 02191cc87e73d..158d91473e56c 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: 2022-09-20 +date: 2022-09-21 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 aa10464a8a61e..8f4d8b0219143 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: 2022-09-20 +date: 2022-09-21 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 0ac409eb1f626..fe62493020308 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: 2022-09-20 +date: 2022-09-21 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 113d794aeac30..c95da8b4cc92f 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: 2022-09-20 +date: 2022-09-21 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 784d4bbb54fd0..655e11aa964bf 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: 2022-09-20 +date: 2022-09-21 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 5097f00e1394f..db40292785ab2 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: 2022-09-20 +date: 2022-09-21 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_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 576f834d1cf4e..5824ea5c73c58 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: 2022-09-20 +date: 2022-09-21 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 75a3bdd71f467..8ec6570a0220e 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: 2022-09-20 +date: 2022-09-21 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 9fc0023c3105f..d9814c190f09f 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: 2022-09-20 +date: 2022-09-21 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 6e659b6749e9b..6744b6d0e1dcd 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: 2022-09-20 +date: 2022-09-21 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 ae651ff396bb2..c3d29d99df19d 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index a5bf07dccef17..80d98d2a35ebe 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index bec95f5dd0edf..e149b42881f92 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-package-json plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] --- import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 15d38db3ce3f8..349e5920113d0 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: 2022-09-20 +date: 2022-09-21 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 286713890035f..99f2f0c8664b2 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: 2022-09-20 +date: 2022-09-21 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 6dcb31e2935ba..8c97882f6aa61 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: 2022-09-20 +date: 2022-09-21 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 f55b78a57dd13..83166d900d2ed 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: 2022-09-20 +date: 2022-09-21 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 368a220dbf198..9230fac245d35 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: 2022-09-20 +date: 2022-09-21 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 a9bab53131ebc..1e3817ccdee9f 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: 2022-09-20 +date: 2022-09-21 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 32bfe1cb2f68b..53a5a76b85ff3 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 4e928b81cc9e2..054c0285c637d 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index 6885c76d34578..afa19269f8816 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] --- import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx index 02d17639ecacb..8c4e404667da3 100644 --- a/api_docs/kbn_type_summarizer_core.mdx +++ b/api_docs/kbn_type_summarizer_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer-core title: "@kbn/type-summarizer-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer-core plugin -date: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core'] --- import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index eee639c93e87c..805990c966ba5 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: 2022-09-20 +date: 2022-09-21 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_theme.devdocs.json b/api_docs/kbn_ui_theme.devdocs.json index c378173a45f13..6dcb3db66223b 100644 --- a/api_docs/kbn_ui_theme.devdocs.json +++ b/api_docs/kbn_ui_theme.devdocs.json @@ -54,7 +54,7 @@ "label": "Theme", "description": [], "signature": [ - "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiPopoverArrowSize: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, @@ -86,7 +86,7 @@ "label": "euiDarkVars", "description": [], "signature": [ - "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiPopoverArrowSize: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, @@ -101,7 +101,7 @@ "label": "euiLightVars", "description": [], "signature": [ - "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiPopoverArrowSize: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, @@ -118,7 +118,7 @@ "\nEUI Theme vars that automatically adjust to light/dark theme" ], "signature": [ - "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiPopoverArrowSize: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "packages/kbn-ui-theme/src/theme.ts", "deprecated": false, diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 76f96eb38b6e5..64654b10b3002 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 93b401d3f3979..e4d20bc32a22e 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: 2022-09-20 +date: 2022-09-21 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 70061bff2f395..a2ab571bf69fa 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: 2022-09-20 +date: 2022-09-21 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 0161668a526f1..0767b1a144f7e 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: 2022-09-20 +date: 2022-09-21 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 58b9be7f437c9..c937c340e4433 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: 2022-09-20 +date: 2022-09-21 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 79ee7cd9f2a58..64f290c135730 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: 2022-09-20 +date: 2022-09-21 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 3fe57352b3d88..da1c2cc403976 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 5677d3738d59b..67182ef5aede3 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -672,7 +672,7 @@ "label": "KibanaThemeProvider", "description": [], "signature": [ - "({ theme$, children }: React.PropsWithChildren) => JSX.Element" + "({ theme$, modify, children }: React.PropsWithChildren) => JSX.Element" ], "path": "src/plugins/kibana_react/public/theme/kibana_theme_provider.tsx", "deprecated": false, @@ -683,7 +683,7 @@ "id": "def-public.KibanaThemeProvider.$1", "type": "CompoundType", "tags": [], - "label": "{ theme$, children }", + "label": "{ theme$, modify, children }", "description": [], "signature": [ "React.PropsWithChildren" @@ -3893,7 +3893,7 @@ "label": "eui", "description": [], "signature": [ - "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiPopoverArrowSize: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" + "{ euiBadgeGroupGutterTypes: { gutterExtraSmall: string; gutterSmall: string; }; euiButtonEmptyTypes: { primary: string; danger: string; disabled: string; ghost: string; text: string; success: string; warning: string; }; euiCallOutTypes: { primary: string; success: string; warning: string; danger: string; }; euiCardSpacing: string; euiCardBottomNodeHeight: string; euiCardSelectButtonBorders: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardSelectButtonBackgrounds: { text: string; primary: string; success: string; danger: string; ghost: string; }; euiCardPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCheckableCardPadding: string; euiCodeBlockPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiCollapsibleNavGroupLightBackgroundColor: string; euiCollapsibleNavGroupDarkBackgroundColor: string; euiCollapsibleNavGroupDarkHighContrastColor: string; euiColorPickerValueRange0: string; euiColorPickerValueRange1: string; euiColorPickerSaturationRange0: string; euiColorPickerSaturationRange1: string; euiColorPickerIndicatorSize: string; euiColorPickerWidth: string; euiColorPaletteDisplaySizes: { sizeExtraSmall: string; sizeSmall: string; sizeMedium: string; }; euiContextMenuWidth: string; euiControlBarBackground: string; euiControlBarText: string; euiControlBarBorderColor: string; euiControlBarInitialHeight: string; euiControlBarMaxHeight: string; euiControlBarHeights: { s: string; m: string; l: string; }; euiDataGridPrefix: string; euiDataGridStyles: string; euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridColumnResizerWidth: string; euiDataGridPopoverMaxHeight: string; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiDataGridVerticalBorder: string; euiSuperDatePickerWidth: string; euiSuperDatePickerButtonWidth: string; euiDragAndDropSpacing: { s: string; m: string; l: string; }; euiEmptyPromptContentMaxWidth: string; gutterTypes: { gutterExtraSmall: string; gutterSmall: string; gutterMedium: string; gutterLarge: string; gutterExtraLarge: string; }; fractions: { fourths: { percentage: string; count: number; }; thirds: { percentage: string; count: number; }; halves: { percentage: string; count: number; }; single: { percentage: string; count: number; }; }; flyoutSizes: { small: { min: string; width: string; max: string; }; medium: { min: string; width: string; max: string; }; large: { min: string; width: string; max: string; }; }; euiFlyoutBorder: string; euiFlyoutPaddingModifiers: { paddingNone: number; paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiFilePickerTallHeight: string; euiRangeLevelColors: { primary: string; success: string; warning: string; danger: string; }; textareaResizing: { vertical: string; horizontal: string; both: string; none: string; }; euiHeaderLinksGutterSizes: { gutterXS: string; gutterS: string; gutterM: string; gutterL: string; }; euiKeyPadMenuSize: string; euiKeyPadMenuMarginSize: string; euiListGroupItemHoverBackground: string; euiListGroupItemHoverBackgroundGhost: string; euiListGroupGutterTypes: { gutterSmall: string; gutterMedium: string; }; euiListGroupItemColorTypes: { primary: string; text: string; subdued: string; ghost: string; }; euiListGroupItemSizeTypes: { xSmall: string; small: string; medium: string; large: string; }; euiMarkdownEditorMinHeight: string; euiResizableButtonTransitionSpeed: string; euiResizableButtonSize: string; euiSelectableListItemBorder: string; euiSelectableListItemPadding: string; euiSelectableTemplateSitewideTypes: { application: { color: string; 'font-weight': number; }; deployment: { color: string; 'font-weight': number; }; article: { color: string; 'font-weight': number; }; case: { color: string; 'font-weight': number; }; platform: { color: string; 'font-weight': number; }; }; euiSideNavEmphasizedBackgroundColor: string; euiSideNavRootTextcolor: string; euiSideNavBranchTextcolor: string; euiSideNavSelectedTextcolor: string; euiSideNavDisabledTextcolor: string; euiStepNumberSize: string; euiStepNumberSmallSize: string; euiStepNumberMargin: string; euiStepStatusColorsToFade: { warning: string; danger: string; disabled: string; incomplete: string; }; euiSuggestItemColors: { tint0: string; tint1: string; tint2: string; tint3: string; tint4: string; tint5: string; tint6: string; tint7: string; tint8: string; tint9: string; tint10: string; }; euiTableCellContentPadding: string; euiTableCellContentPaddingCompressed: string; euiTableCellCheckboxWidth: string; euiTableActionsAreaWidth: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiCodeBlockBackgroundColor: string; euiCodeBlockColor: string; euiCodeBlockSelectedBackgroundColor: string; euiCodeBlockCommentColor: string; euiCodeBlockSelectorTagColor: string; euiCodeBlockStringColor: string; euiCodeBlockTagColor: string; euiCodeBlockNameColor: string; euiCodeBlockNumberColor: string; euiCodeBlockKeywordColor: string; euiCodeBlockFunctionTitleColor: string; euiCodeBlockTypeColor: string; euiCodeBlockAttributeColor: string; euiCodeBlockSymbolColor: string; euiCodeBlockParamsColor: string; euiCodeBlockMetaColor: string; euiCodeBlockTitleColor: string; euiCodeBlockSectionColor: string; euiCodeBlockAdditionColor: string; euiCodeBlockDeletionColor: string; euiCodeBlockSelectorClassColor: string; euiCodeBlockSelectorIdColor: string; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiRangeTrackColor: string; euiRangeThumbRadius: string; euiRangeThumbHeight: string; euiRangeThumbWidth: string; euiRangeThumbBorderColor: string; euiRangeTrackWidth: string; euiRangeTrackHeight: string; euiRangeTrackBorderWidth: number; euiRangeTrackBorderColor: string; euiRangeTrackRadius: string; euiRangeDisabledOpacity: number; euiRangeHighlightHeight: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiButtonMinWidth: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiTooltipBackgroundColor: string; euiTooltipBorderColor: string; euiTooltipAnimations: { top: string; left: string; bottom: string; right: string; }; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; euiDatePickerCalendarWidth: string; euiDatePickerPadding: string; euiDatePickerGap: string; euiDatePickerCalendarColumns: number; euiDatePickerButtonSize: string; euiDatePickerMinControlWidth: string; euiDatePickerMaxControlWidth: string; euiButtonDefaultTransparency: number; euiButtonFontWeight: number; euiRangeHighlightColor: string; euiRangeThumbBackgroundColor: string; euiRangeTrackCompressedHeight: string; euiRangeHighlightCompressedHeight: string; euiRangeHeight: string; euiRangeCompressedHeight: string; euiStepStatusColors: { default: string; complete: string; warning: string; danger: string; }; }" ], "path": "src/plugins/kibana_react/common/eui_styled_components.tsx", "deprecated": false, diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 5dc1c70a12e19..79b13332456d4 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: 2022-09-20 +date: 2022-09-21 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 cbde41998f2e9..676f396e38cc2 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: 2022-09-20 +date: 2022-09-21 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 1b919dd1a45b7..97372d71d53fb 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: 2022-09-20 +date: 2022-09-21 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 724ee8dd1b668..4fc56c34842e9 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -4504,7 +4504,17 @@ "signature": [ "((state: P, references?: ", "SavedObjectReference", - "[] | undefined) => T) | undefined" + "[] | undefined, initialContext?: ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.VisualizeFieldContext", + "text": "VisualizeFieldContext" + }, + " | ", + "VisualizeEditorContext", + " | undefined) => T) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -4540,6 +4550,30 @@ "deprecated": false, "trackAdoption": false, "isRequired": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.fromPersistableState.$3", + "type": "CompoundType", + "tags": [], + "label": "initialContext", + "description": [], + "signature": [ + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.VisualizeFieldContext", + "text": "VisualizeFieldContext" + }, + " | ", + "VisualizeEditorContext", + " | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [] @@ -4642,6 +4676,85 @@ ], "returnComment": [] }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.cloneLayer", + "type": "Function", + "tags": [], + "label": "cloneLayer", + "description": [ + "Reset button on each layer triggers this" + ], + "signature": [ + "((state: T, layerId: string, newLayerId: string, clonedIDsMap: Map) => T) | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.cloneLayer.$1", + "type": "Uncategorized", + "tags": [], + "label": "state", + "description": [], + "signature": [ + "T" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.cloneLayer.$2", + "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.cloneLayer.$3", + "type": "string", + "tags": [], + "label": "newLayerId", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.cloneLayer.$4", + "type": "Object", + "tags": [], + "label": "clonedIDsMap", + "description": [], + "signature": [ + "Map" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "lens", "id": "def-public.Visualization.removeLayer", diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 653131ded02e2..3d5eb7fe015f6 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 640 | 0 | 553 | 41 | +| 646 | 0 | 558 | 42 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 64f0bdfad6df0..3f990bbcb20d0 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: 2022-09-20 +date: 2022-09-21 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 a31914ec5badf..9e7dc24aae0e2 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.devdocs.json b/api_docs/licensing.devdocs.json index 0b456fa70029f..335c7891795d3 100644 --- a/api_docs/licensing.devdocs.json +++ b/api_docs/licensing.devdocs.json @@ -2142,6 +2142,10 @@ "plugin": "searchprofiler", "path": "x-pack/plugins/searchprofiler/server/plugin.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts" + }, { "plugin": "snapshotRestore", "path": "x-pack/plugins/snapshot_restore/server/services/license.ts" diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index c9ddbed424930..c16ee014aeeb8 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: 2022-09-20 +date: 2022-09-21 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 ad79875fc4108..619cdab0943f7 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: 2022-09-20 +date: 2022-09-21 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 cb04898032b5f..4850104f76366 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: 2022-09-20 +date: 2022-09-21 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 fb9923f8b2d6d..57b107d6beadb 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: 2022-09-20 +date: 2022-09-21 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 3b3b444c80646..90a09544d07e7 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: 2022-09-20 +date: 2022-09-21 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 9eacb8772d83d..e430f45966c72 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: 2022-09-20 +date: 2022-09-21 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 ec3b931092bb9..167becc10bb92 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: 2022-09-20 +date: 2022-09-21 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 ec07fb98e351d..5046f23612945 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: 2022-09-20 +date: 2022-09-21 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 e4db7f2310e13..b7f3142a5db26 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: 2022-09-20 +date: 2022-09-21 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 9b47c9ea3d5d1..80dc9cea35aa6 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 25c742a70b12e..9720b4db69b1f 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -738,11 +738,7 @@ }, " | undefined; list: () => string[]; }; selectedAlertId?: string | undefined; } & ", "CommonProps", - " & { as?: \"div\" | undefined; } & _EuiFlyoutProps & Omit, HTMLDivElement>, keyof _EuiFlyoutProps> & Omit, HTMLDivElement>, \"key\" | keyof React.HTMLAttributes | \"css\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }, \"children\" | \"onError\" | \"hidden\" | \"color\" | \"id\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | keyof ", - "CommonProps", - " | keyof React.ClassAttributes | keyof _EuiFlyoutProps>, \"children\" | \"onError\" | \"hidden\" | \"color\" | \"id\" | \"alert\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"key\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"as\" | \"css\" | keyof ", - "CommonProps", - " | \"alerts\" | keyof _EuiFlyoutProps | \"isInApp\" | \"observabilityRuleTypeRegistry\" | \"selectedAlertId\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: ({ alert, alerts, isInApp, observabilityRuleTypeRegistry, onClose, selectedAlertId, }: AlertsFlyoutProps) => JSX.Element | null; }" + " & { as?: \"div\" | undefined; } & _EuiFlyoutProps & Omit, HTMLDivElement>, keyof _EuiFlyoutProps> & Omit, HTMLDivElement>, \"key\" | keyof React.HTMLAttributes | \"css\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }, \"children\" | \"ref\" | \"type\" | \"onError\" | \"hidden\" | \"color\" | \"id\" | \"className\" | \"size\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"key\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"onClose\" | \"data-test-subj\" | \"css\" | \"as\" | \"paddingSize\" | \"focusTrapProps\" | \"ownFocus\" | \"maxWidth\" | \"hideCloseButton\" | \"closeButtonAriaLabel\" | \"closeButtonProps\" | \"closeButtonPosition\" | \"maskProps\" | \"outsideClickCloses\" | \"side\" | \"pushMinBreakpoint\">, \"children\" | \"type\" | \"onError\" | \"hidden\" | \"color\" | \"id\" | \"alert\" | \"className\" | \"size\" | \"title\" | \"onChange\" | \"onKeyDown\" | \"onClick\" | \"security\" | \"key\" | \"defaultValue\" | \"lang\" | \"defaultChecked\" | \"suppressContentEditableWarning\" | \"suppressHydrationWarning\" | \"accessKey\" | \"contentEditable\" | \"contextMenu\" | \"dir\" | \"draggable\" | \"placeholder\" | \"slot\" | \"spellCheck\" | \"style\" | \"tabIndex\" | \"translate\" | \"radioGroup\" | \"role\" | \"about\" | \"datatype\" | \"inlist\" | \"prefix\" | \"property\" | \"resource\" | \"typeof\" | \"vocab\" | \"autoCapitalize\" | \"autoCorrect\" | \"autoSave\" | \"itemProp\" | \"itemScope\" | \"itemType\" | \"itemID\" | \"itemRef\" | \"results\" | \"unselectable\" | \"inputMode\" | \"is\" | \"aria-activedescendant\" | \"aria-atomic\" | \"aria-autocomplete\" | \"aria-busy\" | \"aria-checked\" | \"aria-colcount\" | \"aria-colindex\" | \"aria-colspan\" | \"aria-controls\" | \"aria-current\" | \"aria-describedby\" | \"aria-details\" | \"aria-disabled\" | \"aria-dropeffect\" | \"aria-errormessage\" | \"aria-expanded\" | \"aria-flowto\" | \"aria-grabbed\" | \"aria-haspopup\" | \"aria-hidden\" | \"aria-invalid\" | \"aria-keyshortcuts\" | \"aria-label\" | \"aria-labelledby\" | \"aria-level\" | \"aria-live\" | \"aria-modal\" | \"aria-multiline\" | \"aria-multiselectable\" | \"aria-orientation\" | \"aria-owns\" | \"aria-placeholder\" | \"aria-posinset\" | \"aria-pressed\" | \"aria-readonly\" | \"aria-relevant\" | \"aria-required\" | \"aria-roledescription\" | \"aria-rowcount\" | \"aria-rowindex\" | \"aria-rowspan\" | \"aria-selected\" | \"aria-setsize\" | \"aria-sort\" | \"aria-valuemax\" | \"aria-valuemin\" | \"aria-valuenow\" | \"aria-valuetext\" | \"dangerouslySetInnerHTML\" | \"onCopy\" | \"onCopyCapture\" | \"onCut\" | \"onCutCapture\" | \"onPaste\" | \"onPasteCapture\" | \"onCompositionEnd\" | \"onCompositionEndCapture\" | \"onCompositionStart\" | \"onCompositionStartCapture\" | \"onCompositionUpdate\" | \"onCompositionUpdateCapture\" | \"onFocus\" | \"onFocusCapture\" | \"onBlur\" | \"onBlurCapture\" | \"onChangeCapture\" | \"onBeforeInput\" | \"onBeforeInputCapture\" | \"onInput\" | \"onInputCapture\" | \"onReset\" | \"onResetCapture\" | \"onSubmit\" | \"onSubmitCapture\" | \"onInvalid\" | \"onInvalidCapture\" | \"onLoad\" | \"onLoadCapture\" | \"onErrorCapture\" | \"onKeyDownCapture\" | \"onKeyPress\" | \"onKeyPressCapture\" | \"onKeyUp\" | \"onKeyUpCapture\" | \"onAbort\" | \"onAbortCapture\" | \"onCanPlay\" | \"onCanPlayCapture\" | \"onCanPlayThrough\" | \"onCanPlayThroughCapture\" | \"onDurationChange\" | \"onDurationChangeCapture\" | \"onEmptied\" | \"onEmptiedCapture\" | \"onEncrypted\" | \"onEncryptedCapture\" | \"onEnded\" | \"onEndedCapture\" | \"onLoadedData\" | \"onLoadedDataCapture\" | \"onLoadedMetadata\" | \"onLoadedMetadataCapture\" | \"onLoadStart\" | \"onLoadStartCapture\" | \"onPause\" | \"onPauseCapture\" | \"onPlay\" | \"onPlayCapture\" | \"onPlaying\" | \"onPlayingCapture\" | \"onProgress\" | \"onProgressCapture\" | \"onRateChange\" | \"onRateChangeCapture\" | \"onSeeked\" | \"onSeekedCapture\" | \"onSeeking\" | \"onSeekingCapture\" | \"onStalled\" | \"onStalledCapture\" | \"onSuspend\" | \"onSuspendCapture\" | \"onTimeUpdate\" | \"onTimeUpdateCapture\" | \"onVolumeChange\" | \"onVolumeChangeCapture\" | \"onWaiting\" | \"onWaitingCapture\" | \"onAuxClick\" | \"onAuxClickCapture\" | \"onClickCapture\" | \"onContextMenu\" | \"onContextMenuCapture\" | \"onDoubleClick\" | \"onDoubleClickCapture\" | \"onDrag\" | \"onDragCapture\" | \"onDragEnd\" | \"onDragEndCapture\" | \"onDragEnter\" | \"onDragEnterCapture\" | \"onDragExit\" | \"onDragExitCapture\" | \"onDragLeave\" | \"onDragLeaveCapture\" | \"onDragOver\" | \"onDragOverCapture\" | \"onDragStart\" | \"onDragStartCapture\" | \"onDrop\" | \"onDropCapture\" | \"onMouseDown\" | \"onMouseDownCapture\" | \"onMouseEnter\" | \"onMouseLeave\" | \"onMouseMove\" | \"onMouseMoveCapture\" | \"onMouseOut\" | \"onMouseOutCapture\" | \"onMouseOver\" | \"onMouseOverCapture\" | \"onMouseUp\" | \"onMouseUpCapture\" | \"onSelect\" | \"onSelectCapture\" | \"onTouchCancel\" | \"onTouchCancelCapture\" | \"onTouchEnd\" | \"onTouchEndCapture\" | \"onTouchMove\" | \"onTouchMoveCapture\" | \"onTouchStart\" | \"onTouchStartCapture\" | \"onPointerDown\" | \"onPointerDownCapture\" | \"onPointerMove\" | \"onPointerMoveCapture\" | \"onPointerUp\" | \"onPointerUpCapture\" | \"onPointerCancel\" | \"onPointerCancelCapture\" | \"onPointerEnter\" | \"onPointerEnterCapture\" | \"onPointerLeave\" | \"onPointerLeaveCapture\" | \"onPointerOver\" | \"onPointerOverCapture\" | \"onPointerOut\" | \"onPointerOutCapture\" | \"onGotPointerCapture\" | \"onGotPointerCaptureCapture\" | \"onLostPointerCapture\" | \"onLostPointerCaptureCapture\" | \"onScroll\" | \"onScrollCapture\" | \"onWheel\" | \"onWheelCapture\" | \"onAnimationStart\" | \"onAnimationStartCapture\" | \"onAnimationEnd\" | \"onAnimationEndCapture\" | \"onAnimationIteration\" | \"onAnimationIterationCapture\" | \"onTransitionEnd\" | \"onTransitionEndCapture\" | \"onClose\" | \"data-test-subj\" | \"css\" | \"as\" | \"paddingSize\" | \"focusTrapProps\" | \"ownFocus\" | \"alerts\" | \"maxWidth\" | \"hideCloseButton\" | \"closeButtonAriaLabel\" | \"closeButtonProps\" | \"closeButtonPosition\" | \"maskProps\" | \"outsideClickCloses\" | \"side\" | \"pushMinBreakpoint\" | \"isInApp\" | \"observabilityRuleTypeRegistry\" | \"selectedAlertId\"> & { ref?: React.RefObject | ((instance: HTMLDivElement | null) => void) | null | undefined; }> & { readonly _result: ({ alert, alerts, isInApp, observabilityRuleTypeRegistry, onClose, selectedAlertId, }: AlertsFlyoutProps) => JSX.Element | null; }" ], "path": "x-pack/plugins/observability/public/index.ts", "deprecated": false, @@ -7717,13 +7713,35 @@ "label": "ObservabilityAPIReturnType", "description": [], "signature": [ - "{ \"POST /api/observability/slos\"?: ", + "{ \"DELETE /api/observability/slos/{id}\"?: ", + "ServerRoute", + "<\"DELETE /api/observability/slos/{id}\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ id: ", + "StringC", + "; }>; }>, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteHandlerResources", + "text": "ObservabilityRouteHandlerResources" + }, + ", void, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteCreateOptions", + "text": "ObservabilityRouteCreateOptions" + }, + "> | undefined; \"POST /api/observability/slos\"?: ", "ServerRoute", "<\"POST /api/observability/slos\", ", "TypeC", "<{ body: ", - "IntersectionC", - "<[", "TypeC", "<{ name: ", "StringC", @@ -7821,13 +7839,7 @@ "TypeC", "<{ target: ", "NumberC", - "; }>; }>, ", - "PartialC", - "<{ settings: ", - "PartialC", - "<{ destination_index: ", - "StringC", - "; }>; }>]>; }>, ", + "; }>; }>; }>, ", { "pluginId": "observability", "scope": "server", @@ -7905,13 +7917,35 @@ "label": "ObservabilityServerRouteRepository", "description": [], "signature": [ - "{ \"POST /api/observability/slos\"?: ", + "{ \"DELETE /api/observability/slos/{id}\"?: ", + "ServerRoute", + "<\"DELETE /api/observability/slos/{id}\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ id: ", + "StringC", + "; }>; }>, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteHandlerResources", + "text": "ObservabilityRouteHandlerResources" + }, + ", void, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteCreateOptions", + "text": "ObservabilityRouteCreateOptions" + }, + "> | undefined; \"POST /api/observability/slos\"?: ", "ServerRoute", "<\"POST /api/observability/slos\", ", "TypeC", "<{ body: ", - "IntersectionC", - "<[", "TypeC", "<{ name: ", "StringC", @@ -8009,13 +8043,7 @@ "TypeC", "<{ target: ", "NumberC", - "; }>; }>, ", - "PartialC", - "<{ settings: ", - "PartialC", - "<{ destination_index: ", - "StringC", - "; }>; }>]>; }>, ", + "; }>; }>; }>, ", { "pluginId": "observability", "scope": "server", @@ -9450,6 +9478,126 @@ "trackAdoption": false } ] + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics", + "type": "Object", + "tags": [], + "label": "[enableAwsLambdaMetrics]", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.category", + "type": "Array", + "tags": [], + "label": "category", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [], + "signature": [ + "Type", + "" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.value", + "type": "boolean", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.requiresPageReload", + "type": "boolean", + "tags": [], + "label": "requiresPageReload", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"boolean\"" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableAwsLambdaMetrics.showInLabs", + "type": "boolean", + "tags": [], + "label": "showInLabs", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ] } ], "initialIsOpen": false @@ -9879,6 +10027,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "observability", + "id": "def-common.enableAwsLambdaMetrics", + "type": "string", + "tags": [], + "label": "enableAwsLambdaMetrics", + "description": [], + "signature": [ + "\"observability:enableAwsLambdaMetrics\"" + ], + "path": "x-pack/plugins/observability/common/ui_settings_keys.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "observability", "id": "def-common.enableComparisonByDefault", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index f808ef503a4c0..e4a65ba5f33e7 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Observability UI](https://github.com/orgs/elastic/teams/observability-u | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 509 | 2 | 505 | 30 | +| 519 | 2 | 515 | 30 | ## Client diff --git a/api_docs/osquery.devdocs.json b/api_docs/osquery.devdocs.json index 8d45fc77730ef..bcaaa466f6ca5 100644 --- a/api_docs/osquery.devdocs.json +++ b/api_docs/osquery.devdocs.json @@ -48,6 +48,39 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "osquery", + "id": "def-public.OsqueryPluginStart.OsqueryResults", + "type": "Function", + "tags": [], + "label": "OsqueryResults", + "description": [], + "signature": [ + "(props: ", + "OsqueryActionResultsProps", + ") => JSX.Element" + ], + "path": "x-pack/plugins/osquery/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "osquery", + "id": "def-public.OsqueryPluginStart.OsqueryResults.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "OsqueryActionResultsProps" + ], + "path": "x-pack/plugins/osquery/public/shared_components/lazy_osquery_results.tsx", + "deprecated": false, + "trackAdoption": false + } + ] + }, { "parentPluginId": "osquery", "id": "def-public.OsqueryPluginStart.LiveQueryField", @@ -106,6 +139,53 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "osquery", + "id": "def-public.OsqueryPluginStart.fetchInstallationStatus", + "type": "Function", + "tags": [], + "label": "fetchInstallationStatus", + "description": [], + "signature": [ + "() => { loading: boolean; disabled: boolean; permissionDenied: boolean; }" + ], + "path": "x-pack/plugins/osquery/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "osquery", + "id": "def-public.OsqueryPluginStart.OsqueryResponseActionTypeForm", + "type": "Function", + "tags": [], + "label": "OsqueryResponseActionTypeForm", + "description": [], + "signature": [ + "(props: LazyOsqueryActionParamsFormProps) => JSX.Element" + ], + "path": "x-pack/plugins/osquery/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "osquery", + "id": "def-public.OsqueryPluginStart.OsqueryResponseActionTypeForm.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "LazyOsqueryActionParamsFormProps" + ], + "path": "x-pack/plugins/osquery/public/shared_components/lazy_osquery_action_params_form.tsx", + "deprecated": false, + "trackAdoption": false + } + ] } ], "lifecycle": "start", @@ -129,7 +209,40 @@ "path": "x-pack/plugins/osquery/server/types.ts", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "osquery", + "id": "def-server.OsqueryPluginSetup.osqueryCreateAction", + "type": "Function", + "tags": [], + "label": "osqueryCreateAction", + "description": [], + "signature": [ + "(payload: { agent_ids?: string[] | undefined; agent_all?: boolean | undefined; agent_platforms?: string[] | undefined; agent_policy_ids?: string[] | undefined; query?: string | undefined; queries?: { id: string; query: string; ecs_mapping: { [x: string]: { field?: string | undefined; value?: string | string[] | undefined; }; }; version: string; platform: string; }[] | { [x: string]: { query: string; id: string; ecs_mapping: { [x: string]: { field?: string | undefined; value?: string | string[] | undefined; }; } | undefined; version: string | undefined; platform: string | undefined; saved_query_id: string | undefined; }; } | undefined; saved_query_id?: string | undefined; ecs_mapping?: { [x: string]: { field?: string | undefined; value?: string | string[] | undefined; }; } | undefined; pack_id?: string | undefined; alert_ids?: string[] | undefined; case_ids?: string[] | undefined; event_ids?: string[] | undefined; metadata?: object | undefined; }) => void" + ], + "path": "x-pack/plugins/osquery/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "osquery", + "id": "def-server.OsqueryPluginSetup.osqueryCreateAction.$1", + "type": "Object", + "tags": [], + "label": "payload", + "description": [], + "signature": [ + "{ agent_ids?: string[] | undefined; agent_all?: boolean | undefined; agent_platforms?: string[] | undefined; agent_policy_ids?: string[] | undefined; query?: string | undefined; queries?: { id: string; query: string; ecs_mapping: { [x: string]: { field?: string | undefined; value?: string | string[] | undefined; }; }; version: string; platform: string; }[] | { [x: string]: { query: string; id: string; ecs_mapping: { [x: string]: { field?: string | undefined; value?: string | string[] | undefined; }; } | undefined; version: string | undefined; platform: string | undefined; saved_query_id: string | undefined; }; } | undefined; saved_query_id?: string | undefined; ecs_mapping?: { [x: string]: { field?: string | undefined; value?: string | string[] | undefined; }; } | undefined; pack_id?: string | undefined; alert_ids?: string[] | undefined; case_ids?: string[] | undefined; event_ids?: string[] | undefined; metadata?: object | undefined; }" + ], + "path": "x-pack/plugins/osquery/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], "lifecycle": "setup", "initialIsOpen": true }, diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 39fb0bbcd0e5d..f87b8903f184c 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Security asset management](https://github.com/orgs/elastic/teams/securi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 14 | 0 | 14 | 2 | +| 21 | 0 | 21 | 3 | ## Client diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index f579ba9e630fb..9bc3e41f6b9e1 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: 2022-09-20 +date: 2022-09-21 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 | |--------------|----------|------------------------| -| 460 | 386 | 38 | +| 462 | 388 | 38 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 31149 | 179 | 20873 | 982 | +| 31334 | 180 | 21000 | 980 | ## Plugin Directory @@ -31,17 +31,18 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 1 | 32 | 2 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 9 | 0 | 0 | 2 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 370 | 0 | 361 | 22 | -| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 38 | 0 | 38 | 52 | +| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 38 | 0 | 38 | 51 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 80 | 1 | 71 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | | | [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 87 | 0 | 71 | 28 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 264 | 2 | 249 | 9 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 29 | 0 | 24 | 0 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/@elastic/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. | 16 | 0 | 0 | 0 | | | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 18 | 0 | 2 | 3 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 | | | [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 | 212 | 0 | 204 | 7 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2657 | 0 | 45 | 2 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2684 | 0 | 45 | 0 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 103 | 0 | 84 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 144 | 0 | 139 | 10 | @@ -53,7 +54,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 966 | 0 | 208 | 1 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 1 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 | -| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 96 | 0 | 79 | 4 | +| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 97 | 0 | 80 | 4 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 515 | 0 | 415 | 4 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | @@ -80,7 +81,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 5 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | 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/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 240 | 0 | 6 | 2 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 974 | 3 | 874 | 17 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 986 | 3 | 886 | 17 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -100,7 +101,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | kibanaUsageCollection | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 615 | 3 | 418 | 9 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | 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. | 640 | 0 | 553 | 41 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | 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. | 646 | 0 | 558 | 42 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | @@ -114,15 +115,15 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 34 | 0 | 34 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | -| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 509 | 2 | 505 | 30 | -| | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 14 | 0 | 14 | 2 | +| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 519 | 2 | 515 | 30 | +| | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 21 | 0 | 21 | 3 | | painlessLab | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [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). | 243 | 2 | 187 | 12 | | | [profiling](https://github.com/orgs/elastic/teams/profiling-ui) | - | 14 | 1 | 14 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 | | | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 36 | 0 | 16 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 21 | 0 | 21 | 0 | -| | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 215 | 0 | 187 | 11 | +| | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 230 | 0 | 202 | 10 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 24 | 0 | 19 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 193 | 2 | 152 | 5 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 16 | 0 | 16 | 0 | @@ -134,7 +135,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 4 | | searchprofiler | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 247 | 0 | 90 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 54 | 0 | 53 | 22 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 55 | 0 | 54 | 23 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 114 | 0 | 55 | 10 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 22 | 1 | 22 | 1 | @@ -151,9 +152,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 450 | 1 | 344 | 33 | | | [Machine Learning 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 | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 428 | 0 | 407 | 46 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 437 | 1 | 416 | 45 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 132 | 0 | 91 | 11 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 205 | 0 | 142 | 9 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 206 | 0 | 142 | 9 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list which can be integrated into apps | 61 | 0 | 59 | 2 | | | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 122 | 2 | 96 | 16 | | upgradeAssistant | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | @@ -174,7 +175,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 26 | 0 | 25 | 1 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 53 | 0 | 50 | 5 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 611 | 12 | 582 | 14 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 630 | 12 | 601 | 14 | | watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | ## Package Directory @@ -295,9 +296,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 5 | 0 | 0 | 0 | | | Kibana Core | - | 6 | 0 | 6 | 0 | | | Kibana Core | - | 2 | 0 | 2 | 0 | -| | Kibana Core | - | 94 | 1 | 66 | 0 | -| | Kibana Core | - | 289 | 1 | 126 | 0 | -| | Kibana Core | - | 68 | 0 | 49 | 0 | +| | Kibana Core | - | 106 | 1 | 75 | 0 | +| | Kibana Core | - | 308 | 1 | 137 | 0 | +| | Kibana Core | - | 71 | 0 | 51 | 0 | | | Kibana Core | - | 6 | 0 | 6 | 0 | | | Kibana Core | - | 37 | 0 | 31 | 1 | | | Kibana Core | - | 4 | 0 | 4 | 0 | @@ -310,7 +311,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 100 | 0 | 74 | 43 | | | Kibana Core | - | 12 | 0 | 12 | 0 | | | Kibana Core | - | 225 | 0 | 82 | 0 | -| | Kibana Core | - | 66 | 0 | 66 | 4 | +| | Kibana Core | - | 69 | 0 | 69 | 4 | | | Kibana Core | - | 14 | 0 | 13 | 0 | | | Kibana Core | - | 99 | 1 | 86 | 0 | | | Kibana Core | - | 12 | 0 | 2 | 0 | @@ -330,7 +331,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 27 | 1 | 13 | 0 | | | Kibana Core | - | 28 | 1 | 27 | 1 | | | Kibana Core | - | 6 | 0 | 6 | 0 | -| | Kibana Core | - | 146 | 0 | 135 | 0 | +| | Kibana Core | - | 153 | 0 | 142 | 0 | | | Kibana Core | - | 8 | 0 | 8 | 2 | | | Kibana Core | - | 7 | 0 | 7 | 0 | | | [Owner missing] | - | 13 | 0 | 7 | 0 | @@ -346,6 +347,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Owner missing] | - | 27 | 0 | 14 | 1 | | | Kibana Core | - | 7 | 0 | 3 | 0 | | | [Owner missing] | - | 222 | 1 | 168 | 12 | +| | Kibana Core | - | 11 | 0 | 11 | 0 | | | [Owner missing] | - | 2 | 0 | 1 | 0 | | | [Owner missing] | - | 20 | 0 | 16 | 0 | | | [Owner missing] | - | 2 | 0 | 0 | 0 | @@ -365,7 +367,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 8 | 0 | 8 | 0 | | | [Owner missing] | - | 6 | 0 | 1 | 1 | | | [Owner missing] | - | 534 | 1 | 1 | 0 | -| | Machine Learning UI | This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification. | 58 | 2 | 39 | 3 | +| | Machine Learning UI | This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification. | 64 | 2 | 44 | 3 | | | Machine Learning UI | A type guard to check record like object structures. | 3 | 0 | 2 | 0 | | | Machine Learning UI | Creates a deterministic number based hash out of a string. | 2 | 0 | 1 | 0 | | | [Owner missing] | - | 55 | 0 | 55 | 2 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index b7d546ea5bb4c..5c1ba3fbe59be 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: 2022-09-20 +date: 2022-09-21 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 018931d925b07..aa3a5a11aa480 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: 2022-09-20 +date: 2022-09-21 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 b74c2aad10f9a..c20d0362bae48 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: 2022-09-20 +date: 2022-09-21 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 ad3ea82997456..b58df3eacde86 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index b816147f94c89..8f47f3dda1591 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.devdocs.json b/api_docs/rule_registry.devdocs.json index 8d63050c8a9b0..424057fd0db70 100644 --- a/api_docs/rule_registry.devdocs.json +++ b/api_docs/rule_registry.devdocs.json @@ -411,7 +411,13 @@ "description": [], "signature": [ "({ indices, metaFields, allowNoIndex, }: { indices: string[]; metaFields: string[]; allowNoIndex: boolean; }) => Promise<", - "BrowserFields", + { + "pluginId": "ruleRegistry", + "scope": "common", + "docId": "kibRuleRegistryPluginApi", + "section": "def-common.BrowserFields", + "text": "BrowserFields" + }, ">" ], "path": "x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts", @@ -3985,6 +3991,200 @@ } ], "interfaces": [ + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField", + "type": "Interface", + "tags": [], + "label": "BrowserField", + "description": [], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.aggregatable", + "type": "boolean", + "tags": [], + "label": "aggregatable", + "description": [], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.category", + "type": "string", + "tags": [], + "label": "category", + "description": [], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.description", + "type": "CompoundType", + "tags": [], + "label": "description", + "description": [], + "signature": [ + "string | null | undefined" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.example", + "type": "CompoundType", + "tags": [], + "label": "example", + "description": [], + "signature": [ + "string | number | null | undefined" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.fields", + "type": "Object", + "tags": [], + "label": "fields", + "description": [], + "signature": [ + "{ readonly [x: string]: Partial<", + { + "pluginId": "ruleRegistry", + "scope": "common", + "docId": "kibRuleRegistryPluginApi", + "section": "def-common.BrowserField", + "text": "BrowserField" + }, + ">; }" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.format", + "type": "string", + "tags": [], + "label": "format", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.indexes", + "type": "Array", + "tags": [], + "label": "indexes", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.searchable", + "type": "boolean", + "tags": [], + "label": "searchable", + "description": [], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.subType", + "type": "CompoundType", + "tags": [], + "label": "subType", + "description": [], + "signature": [ + "IFieldSubType", + " | undefined" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.readFromDocValues", + "type": "boolean", + "tags": [], + "label": "readFromDocValues", + "description": [], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserField.runtimeField", + "type": "Object", + "tags": [], + "label": "runtimeField", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.RuntimeField", + "text": "RuntimeField" + }, + " | undefined" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "ruleRegistry", "id": "def-common.RuleRegistrySearchRequestPagination", @@ -4039,6 +4239,29 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "ruleRegistry", + "id": "def-common.BrowserFields", + "type": "Type", + "tags": [], + "label": "BrowserFields", + "description": [], + "signature": [ + "{ [x: string]: Partial<", + { + "pluginId": "ruleRegistry", + "scope": "common", + "docId": "kibRuleRegistryPluginApi", + "section": "def-common.BrowserField", + "text": "BrowserField" + }, + ">; }" + ], + "path": "x-pack/plugins/rule_registry/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "ruleRegistry", "id": "def-common.ParsedTechnicalFields", diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 10e3e605e3dbe..1e009c82de870 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; @@ -21,7 +21,7 @@ Contact [RAC](https://github.com/orgs/elastic/teams/rac) for questions regarding | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 215 | 0 | 187 | 11 | +| 230 | 0 | 202 | 10 | ## Server diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index aed78d453b32a..bf84cc9fa0b90 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index f03ea7d006a30..8fb8ea0d3c2b7 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index b2785bd5fedfc..c9b068a72abff 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.devdocs.json b/api_docs/saved_objects_management.devdocs.json index 3c4ff5fc143a3..1f64f3bea1abe 100644 --- a/api_docs/saved_objects_management.devdocs.json +++ b/api_docs/saved_objects_management.devdocs.json @@ -310,7 +310,11 @@ "section": "def-public.SavedObjectsManagementRecord", "text": "SavedObjectsManagementRecord" }, - "; headers?: string | undefined; defaultValue?: string | number | readonly string[] | undefined; lang?: string | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; role?: React.AriaRole | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"email\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: Booleanish | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: Booleanish | undefined; 'aria-checked'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"time\" | \"page\" | \"false\" | \"true\" | \"step\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: Booleanish | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: Booleanish | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: Booleanish | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"false\" | \"true\" | \"dialog\" | \"listbox\" | \"tree\" | undefined; 'aria-hidden'?: Booleanish | undefined; 'aria-invalid'?: boolean | \"false\" | \"true\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: Booleanish | undefined; 'aria-multiline'?: Booleanish | undefined; 'aria-multiselectable'?: Booleanish | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-readonly'?: Booleanish | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: Booleanish | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: Booleanish | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"other\" | \"ascending\" | \"descending\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; height?: string | number | undefined; width?: string | undefined; readOnly?: boolean | undefined; align?: ", + "; headers?: string | undefined; defaultValue?: string | number | readonly string[] | undefined; lang?: string | undefined; defaultChecked?: boolean | undefined; suppressContentEditableWarning?: boolean | undefined; suppressHydrationWarning?: boolean | undefined; accessKey?: string | undefined; contentEditable?: \"inherit\" | Booleanish | undefined; contextMenu?: string | undefined; dir?: string | undefined; draggable?: Booleanish | undefined; placeholder?: string | undefined; slot?: string | undefined; spellCheck?: Booleanish | undefined; style?: React.CSSProperties | undefined; tabIndex?: number | undefined; translate?: \"no\" | \"yes\" | undefined; radioGroup?: string | undefined; role?: React.AriaRole | undefined; about?: string | undefined; datatype?: string | undefined; inlist?: any; prefix?: string | undefined; property?: string | undefined; resource?: string | undefined; typeof?: string | undefined; vocab?: string | undefined; autoCapitalize?: string | undefined; autoCorrect?: string | undefined; autoSave?: string | undefined; itemProp?: string | undefined; itemScope?: boolean | undefined; itemType?: string | undefined; itemID?: string | undefined; itemRef?: string | undefined; results?: number | undefined; unselectable?: \"on\" | \"off\" | undefined; inputMode?: \"none\" | \"email\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"numeric\" | \"decimal\" | undefined; is?: string | undefined; 'aria-activedescendant'?: string | undefined; 'aria-atomic'?: Booleanish | undefined; 'aria-autocomplete'?: \"none\" | \"list\" | \"inline\" | \"both\" | undefined; 'aria-busy'?: Booleanish | undefined; 'aria-checked'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-colcount'?: number | undefined; 'aria-colindex'?: number | undefined; 'aria-colspan'?: number | undefined; 'aria-controls'?: string | undefined; 'aria-current'?: boolean | \"date\" | \"location\" | \"time\" | \"page\" | \"false\" | \"true\" | \"step\" | undefined; 'aria-describedby'?: string | undefined; 'aria-details'?: string | undefined; 'aria-disabled'?: Booleanish | undefined; 'aria-dropeffect'?: \"none\" | \"copy\" | \"link\" | \"execute\" | \"move\" | \"popup\" | undefined; 'aria-errormessage'?: string | undefined; 'aria-expanded'?: Booleanish | undefined; 'aria-flowto'?: string | undefined; 'aria-grabbed'?: Booleanish | undefined; 'aria-haspopup'?: boolean | \"grid\" | \"menu\" | \"false\" | \"true\" | \"dialog\" | \"listbox\" | \"tree\" | undefined; 'aria-hidden'?: Booleanish | undefined; 'aria-invalid'?: boolean | \"false\" | \"true\" | \"grammar\" | \"spelling\" | undefined; 'aria-keyshortcuts'?: string | undefined; 'aria-label'?: string | undefined; 'aria-labelledby'?: string | undefined; 'aria-level'?: number | undefined; 'aria-live'?: \"off\" | \"assertive\" | \"polite\" | undefined; 'aria-modal'?: Booleanish | undefined; 'aria-multiline'?: Booleanish | undefined; 'aria-multiselectable'?: Booleanish | undefined; 'aria-orientation'?: \"horizontal\" | \"vertical\" | undefined; 'aria-owns'?: string | undefined; 'aria-placeholder'?: string | undefined; 'aria-posinset'?: number | undefined; 'aria-pressed'?: boolean | \"mixed\" | \"false\" | \"true\" | undefined; 'aria-readonly'?: Booleanish | undefined; 'aria-relevant'?: \"all\" | \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\" | undefined; 'aria-required'?: Booleanish | undefined; 'aria-roledescription'?: string | undefined; 'aria-rowcount'?: number | undefined; 'aria-rowindex'?: number | undefined; 'aria-rowspan'?: number | undefined; 'aria-selected'?: Booleanish | undefined; 'aria-setsize'?: number | undefined; 'aria-sort'?: \"none\" | \"other\" | \"ascending\" | \"descending\" | undefined; 'aria-valuemax'?: number | undefined; 'aria-valuemin'?: number | undefined; 'aria-valuenow'?: number | undefined; 'aria-valuetext'?: string | undefined; dangerouslySetInnerHTML?: { __html: string; } | undefined; onCopy?: React.ClipboardEventHandler | undefined; onCopyCapture?: React.ClipboardEventHandler | undefined; onCut?: React.ClipboardEventHandler | undefined; onCutCapture?: React.ClipboardEventHandler | undefined; onPaste?: React.ClipboardEventHandler | undefined; onPasteCapture?: React.ClipboardEventHandler | undefined; onCompositionEnd?: React.CompositionEventHandler | undefined; onCompositionEndCapture?: React.CompositionEventHandler | undefined; onCompositionStart?: React.CompositionEventHandler | undefined; onCompositionStartCapture?: React.CompositionEventHandler | undefined; onCompositionUpdate?: React.CompositionEventHandler | undefined; onCompositionUpdateCapture?: React.CompositionEventHandler | undefined; onFocus?: React.FocusEventHandler | undefined; onFocusCapture?: React.FocusEventHandler | undefined; onBlur?: React.FocusEventHandler | undefined; onBlurCapture?: React.FocusEventHandler | undefined; onChangeCapture?: React.FormEventHandler | undefined; onBeforeInput?: React.FormEventHandler | undefined; onBeforeInputCapture?: React.FormEventHandler | undefined; onInput?: React.FormEventHandler | undefined; onInputCapture?: React.FormEventHandler | undefined; onReset?: React.FormEventHandler | undefined; onResetCapture?: React.FormEventHandler | undefined; onSubmit?: React.FormEventHandler | undefined; onSubmitCapture?: React.FormEventHandler | undefined; onInvalid?: React.FormEventHandler | undefined; onInvalidCapture?: React.FormEventHandler | undefined; onLoad?: React.ReactEventHandler | undefined; onLoadCapture?: React.ReactEventHandler | undefined; onErrorCapture?: React.ReactEventHandler | undefined; onKeyDownCapture?: React.KeyboardEventHandler | undefined; onKeyPress?: React.KeyboardEventHandler | undefined; onKeyPressCapture?: React.KeyboardEventHandler | undefined; onKeyUp?: React.KeyboardEventHandler | undefined; onKeyUpCapture?: React.KeyboardEventHandler | undefined; onAbort?: React.ReactEventHandler | undefined; onAbortCapture?: React.ReactEventHandler | undefined; onCanPlay?: React.ReactEventHandler | undefined; onCanPlayCapture?: React.ReactEventHandler | undefined; onCanPlayThrough?: React.ReactEventHandler | undefined; onCanPlayThroughCapture?: React.ReactEventHandler | undefined; onDurationChange?: React.ReactEventHandler | undefined; onDurationChangeCapture?: React.ReactEventHandler | undefined; onEmptied?: React.ReactEventHandler | undefined; onEmptiedCapture?: React.ReactEventHandler | undefined; onEncrypted?: React.ReactEventHandler | undefined; onEncryptedCapture?: React.ReactEventHandler | undefined; onEnded?: React.ReactEventHandler | undefined; onEndedCapture?: React.ReactEventHandler | undefined; onLoadedData?: React.ReactEventHandler | undefined; onLoadedDataCapture?: React.ReactEventHandler | undefined; onLoadedMetadata?: React.ReactEventHandler | undefined; onLoadedMetadataCapture?: React.ReactEventHandler | undefined; onLoadStart?: React.ReactEventHandler | undefined; onLoadStartCapture?: React.ReactEventHandler | undefined; onPause?: React.ReactEventHandler | undefined; onPauseCapture?: React.ReactEventHandler | undefined; onPlay?: React.ReactEventHandler | undefined; onPlayCapture?: React.ReactEventHandler | undefined; onPlaying?: React.ReactEventHandler | undefined; onPlayingCapture?: React.ReactEventHandler | undefined; onProgress?: React.ReactEventHandler | undefined; onProgressCapture?: React.ReactEventHandler | undefined; onRateChange?: React.ReactEventHandler | undefined; onRateChangeCapture?: React.ReactEventHandler | undefined; onSeeked?: React.ReactEventHandler | undefined; onSeekedCapture?: React.ReactEventHandler | undefined; onSeeking?: React.ReactEventHandler | undefined; onSeekingCapture?: React.ReactEventHandler | undefined; onStalled?: React.ReactEventHandler | undefined; onStalledCapture?: React.ReactEventHandler | undefined; onSuspend?: React.ReactEventHandler | undefined; onSuspendCapture?: React.ReactEventHandler | undefined; onTimeUpdate?: React.ReactEventHandler | undefined; onTimeUpdateCapture?: React.ReactEventHandler | undefined; onVolumeChange?: React.ReactEventHandler | undefined; onVolumeChangeCapture?: React.ReactEventHandler | undefined; onWaiting?: React.ReactEventHandler | undefined; onWaitingCapture?: React.ReactEventHandler | undefined; onAuxClick?: React.MouseEventHandler | undefined; onAuxClickCapture?: React.MouseEventHandler | undefined; onClickCapture?: React.MouseEventHandler | undefined; onContextMenu?: React.MouseEventHandler | undefined; onContextMenuCapture?: React.MouseEventHandler | undefined; onDoubleClick?: React.MouseEventHandler | undefined; onDoubleClickCapture?: React.MouseEventHandler | undefined; onDrag?: React.DragEventHandler | undefined; onDragCapture?: React.DragEventHandler | undefined; onDragEnd?: React.DragEventHandler | undefined; onDragEndCapture?: React.DragEventHandler | undefined; onDragEnter?: React.DragEventHandler | undefined; onDragEnterCapture?: React.DragEventHandler | undefined; onDragExit?: React.DragEventHandler | undefined; onDragExitCapture?: React.DragEventHandler | undefined; onDragLeave?: React.DragEventHandler | undefined; onDragLeaveCapture?: React.DragEventHandler | undefined; onDragOver?: React.DragEventHandler | undefined; onDragOverCapture?: React.DragEventHandler | undefined; onDragStart?: React.DragEventHandler | undefined; onDragStartCapture?: React.DragEventHandler | undefined; onDrop?: React.DragEventHandler | undefined; onDropCapture?: React.DragEventHandler | undefined; onMouseDown?: React.MouseEventHandler | undefined; onMouseDownCapture?: React.MouseEventHandler | undefined; onMouseEnter?: React.MouseEventHandler | undefined; onMouseLeave?: React.MouseEventHandler | undefined; onMouseMove?: React.MouseEventHandler | undefined; onMouseMoveCapture?: React.MouseEventHandler | undefined; onMouseOut?: React.MouseEventHandler | undefined; onMouseOutCapture?: React.MouseEventHandler | undefined; onMouseOver?: React.MouseEventHandler | undefined; onMouseOverCapture?: React.MouseEventHandler | undefined; onMouseUp?: React.MouseEventHandler | undefined; onMouseUpCapture?: React.MouseEventHandler | undefined; onSelect?: React.ReactEventHandler | undefined; onSelectCapture?: React.ReactEventHandler | undefined; onTouchCancel?: React.TouchEventHandler | undefined; onTouchCancelCapture?: React.TouchEventHandler | undefined; onTouchEnd?: React.TouchEventHandler | undefined; onTouchEndCapture?: React.TouchEventHandler | undefined; onTouchMove?: React.TouchEventHandler | undefined; onTouchMoveCapture?: React.TouchEventHandler | undefined; onTouchStart?: React.TouchEventHandler | undefined; onTouchStartCapture?: React.TouchEventHandler | undefined; onPointerDown?: React.PointerEventHandler | undefined; onPointerDownCapture?: React.PointerEventHandler | undefined; onPointerMove?: React.PointerEventHandler | undefined; onPointerMoveCapture?: React.PointerEventHandler | undefined; onPointerUp?: React.PointerEventHandler | undefined; onPointerUpCapture?: React.PointerEventHandler | undefined; onPointerCancel?: React.PointerEventHandler | undefined; onPointerCancelCapture?: React.PointerEventHandler | undefined; onPointerEnter?: React.PointerEventHandler | undefined; onPointerEnterCapture?: React.PointerEventHandler | undefined; onPointerLeave?: React.PointerEventHandler | undefined; onPointerLeaveCapture?: React.PointerEventHandler | undefined; onPointerOver?: React.PointerEventHandler | undefined; onPointerOverCapture?: React.PointerEventHandler | undefined; onPointerOut?: React.PointerEventHandler | undefined; onPointerOutCapture?: React.PointerEventHandler | undefined; onGotPointerCapture?: React.PointerEventHandler | undefined; onGotPointerCaptureCapture?: React.PointerEventHandler | undefined; onLostPointerCapture?: React.PointerEventHandler | undefined; onLostPointerCaptureCapture?: React.PointerEventHandler | undefined; onScroll?: React.UIEventHandler | undefined; onScrollCapture?: React.UIEventHandler | undefined; onWheel?: React.WheelEventHandler | undefined; onWheelCapture?: React.WheelEventHandler | undefined; onAnimationStart?: React.AnimationEventHandler | undefined; onAnimationStartCapture?: React.AnimationEventHandler | undefined; onAnimationEnd?: React.AnimationEventHandler | undefined; onAnimationEndCapture?: React.AnimationEventHandler | undefined; onAnimationIteration?: React.AnimationEventHandler | undefined; onAnimationIterationCapture?: React.AnimationEventHandler | undefined; onTransitionEnd?: React.TransitionEventHandler | undefined; onTransitionEndCapture?: React.TransitionEventHandler | undefined; 'data-test-subj'?: string | undefined; css?: ", + "Interpolation", + "<", + "Theme", + ">; height?: string | number | undefined; width?: string | undefined; readOnly?: boolean | undefined; align?: ", "HorizontalAlignment", " | undefined; abbr?: string | undefined; footer?: string | React.ReactElement> | ((props: ", "EuiTableFooterProps", diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index e2f4168974e43..a93096c35f284 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: 2022-09-20 +date: 2022-09-21 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 a354225c86402..5c0f411010392 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 50182897c2fbd..9eccbd9ed489d 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: 2022-09-20 +date: 2022-09-21 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 df41afa0216df..6f35997066953 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: 2022-09-20 +date: 2022-09-21 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 f3de4702d11b1..e66c9d7da18f5 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: 2022-09-20 +date: 2022-09-21 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 7bcef95c29df0..a09ddaab21afb 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: 2022-09-20 +date: 2022-09-21 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 9f6f7650337cb..fedcffb1b25d5 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 5827c20db016b..a67fa886963b7 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -64,7 +64,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly disableIsolationUIPendingStatuses: boolean; readonly pendingActionResponsesWithAck: boolean; readonly policyListEnabled: boolean; readonly policyResponseInFleetEnabled: boolean; readonly threatIntelligenceEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly responseActionsConsoleEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly disableIsolationUIPendingStatuses: boolean; readonly pendingActionResponsesWithAck: boolean; readonly policyListEnabled: boolean; readonly policyResponseInFleetEnabled: boolean; readonly threatIntelligenceEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly responseActionsConsoleEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/plugin.tsx", "deprecated": false, @@ -1080,6 +1080,20 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "securitySolution", + "id": "def-server.SecuritySolutionApiRequestHandlerContext.getQueryRuleAdditionalOptions", + "type": "Object", + "tags": [], + "label": "getQueryRuleAdditionalOptions", + "description": [], + "signature": [ + "CreateQueryRuleAdditionalOptions" + ], + "path": "x-pack/plugins/security_solution/server/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -1095,7 +1109,7 @@ "label": "ConfigType", "description": [], "signature": [ - "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; prebuiltRulesFromFileSystem: boolean; prebuiltRulesFromSavedObjects: boolean; }> & { experimentalFeatures: Readonly<{ tGridEnabled: boolean; tGridEventRenderedViewEnabled: boolean; excludePoliciesInFilterEnabled: boolean; kubernetesEnabled: boolean; disableIsolationUIPendingStatuses: boolean; pendingActionResponsesWithAck: boolean; policyListEnabled: boolean; policyResponseInFleetEnabled: boolean; threatIntelligenceEnabled: boolean; previewTelemetryUrlEnabled: boolean; responseActionsConsoleEnabled: boolean; insightsRelatedAlertsByProcessAncestry: boolean; extendedRuleExecutionLoggingEnabled: boolean; socTrendsEnabled: boolean; }>; }" + "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; prebuiltRulesFromFileSystem: boolean; prebuiltRulesFromSavedObjects: boolean; }> & { experimentalFeatures: Readonly<{ tGridEnabled: boolean; tGridEventRenderedViewEnabled: boolean; excludePoliciesInFilterEnabled: boolean; kubernetesEnabled: boolean; disableIsolationUIPendingStatuses: boolean; pendingActionResponsesWithAck: boolean; policyListEnabled: boolean; policyResponseInFleetEnabled: boolean; threatIntelligenceEnabled: boolean; previewTelemetryUrlEnabled: boolean; responseActionsConsoleEnabled: boolean; insightsRelatedAlertsByProcessAncestry: boolean; extendedRuleExecutionLoggingEnabled: boolean; socTrendsEnabled: boolean; responseActionsEnabled: boolean; }>; }" ], "path": "x-pack/plugins/security_solution/server/config.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 5022716224980..60d6c667f7c91 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Security solution](https://github.com/orgs/elastic/teams/security-solut | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 54 | 0 | 53 | 22 | +| 55 | 0 | 54 | 23 | ## Client diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 25ab4bd3d6c53..408b96cf182b1 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: 2022-09-20 +date: 2022-09-21 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 017d32c37d4f7..e0a7355048af7 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: 2022-09-20 +date: 2022-09-21 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 c6c6e0cc46148..e4f72340d087e 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: 2022-09-20 +date: 2022-09-21 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 1ffb54e68ed96..98cb1380a3503 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: 2022-09-20 +date: 2022-09-21 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 d50a8500a951d..0d23909034ae8 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: 2022-09-20 +date: 2022-09-21 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 dcbc38512094c..8b250938595f7 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: 2022-09-20 +date: 2022-09-21 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 de40bcf02dc92..d33ad32bec354 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: 2022-09-20 +date: 2022-09-21 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 fd689d3934388..d170306872998 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: 2022-09-20 +date: 2022-09-21 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 f1d4653b9dc81..6f9d668fb6cea 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: 2022-09-20 +date: 2022-09-21 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 89a20be1cb5fa..ed6b7e61717c5 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: 2022-09-20 +date: 2022-09-21 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 b945f23a74e3a..7ad0996faeb49 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index d2593dcd4c562..341dca64a770b 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 4bd6794b21f76..ef634330a3c39 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 4868243b57664..d4370cbd83025 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 77ded4f84172b..42809d2bac92c 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -2339,6 +2339,150 @@ "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.browserFields", + "type": "Any", + "tags": [], + "label": "browserFields", + "description": [], + "signature": [ + "any" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onToggleColumn", + "type": "Function", + "tags": [], + "label": "onToggleColumn", + "description": [], + "signature": [ + "(columnId: string) => void" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onToggleColumn.$1", + "type": "string", + "tags": [], + "label": "columnId", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onResetColumns", + "type": "Function", + "tags": [], + "label": "onResetColumns", + "description": [], + "signature": [ + "() => void" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onColumnsChange", + "type": "Function", + "tags": [], + "label": "onColumnsChange", + "description": [], + "signature": [ + "(columns: ", + "EuiDataGridColumn", + "[], visibleColumns: string[]) => void" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onColumnsChange.$1", + "type": "Array", + "tags": [], + "label": "columns", + "description": [], + "signature": [ + "EuiDataGridColumn", + "[]" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onColumnsChange.$2", + "type": "Array", + "tags": [], + "label": "visibleColumns", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onChangeVisibleColumns", + "type": "Function", + "tags": [], + "label": "onChangeVisibleColumns", + "description": [], + "signature": [ + "(newColumns: string[]) => void" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertsTableProps.onChangeVisibleColumns.$1", + "type": "Array", + "tags": [], + "label": "newColumns", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -2766,8 +2910,14 @@ "A map of categoryId -> metadata about the fields in that category" ], "signature": [ - "{ readonly [x: string]: Partial<", - "BrowserField", + "{ [x: string]: Partial<", + { + "pluginId": "ruleRegistry", + "scope": "common", + "docId": "kibRuleRegistryPluginApi", + "section": "def-common.BrowserField", + "text": "BrowserField" + }, ">; }" ], "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/types.ts", diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index b81484ae1426f..6c8003d4f5dfd 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 428 | 0 | 407 | 46 | +| 437 | 1 | 416 | 45 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 8b6617ccdb0c0..146259f72f7bb 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.devdocs.json b/api_docs/ui_actions_enhanced.devdocs.json index f4fbda2b1815f..923b69011b532 100644 --- a/api_docs/ui_actions_enhanced.devdocs.json +++ b/api_docs/ui_actions_enhanced.devdocs.json @@ -2854,7 +2854,7 @@ "tags": [], "label": "getDisplayName", "description": [ - "\nShould return an internationalized name of the drilldown, which will be\ndisplayed to the user." + "\nShould return an internationalized name of the drilldown, which will be\ndisplayed to the user as the name of drilldown factory when configuring a drilldown." ], "signature": [ "() => string" @@ -2865,6 +2865,45 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "uiActionsEnhanced", + "id": "def-public.DrilldownDefinition.actionMenuItem", + "type": "Function", + "tags": [], + "label": "actionMenuItem", + "description": [ + "\nName of the drilldown instance displayed to the user at the moment of\ndrilldown execution. Should be internationalized." + ], + "signature": [ + { + "pluginId": "kibanaUtils", + "scope": "common", + "docId": "kibKibanaUtilsPluginApi", + "section": "def-common.UiComponent", + "text": "UiComponent" + }, + "<{ config: Omit<", + { + "pluginId": "uiActionsEnhanced", + "scope": "common", + "docId": "kibUiActionsEnhancedPluginApi", + "section": "def-common.SerializedAction", + "text": "SerializedAction" + }, + ", \"factoryId\">; context: ExecutionContext | ", + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionExecutionContext", + "text": "ActionExecutionContext" + }, + "; }> | undefined" + ], + "path": "src/plugins/ui_actions_enhanced/public/drilldowns/drilldown_definition.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "uiActionsEnhanced", "id": "def-public.DrilldownDefinition.isCompatible", diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index d9207909cfb57..427db15b1b3ad 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 205 | 0 | 142 | 9 | +| 206 | 0 | 142 | 9 | ## Client diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index f64afc9f9b339..4d489503da198 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index eb27791b68225..67b3d84096fc4 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: 2022-09-20 +date: 2022-09-21 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 307924444436a..9d8991e0ea45d 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: 2022-09-20 +date: 2022-09-21 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 4718f11d57d79..46e7ae60e2614 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: 2022-09-20 +date: 2022-09-21 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 474edc06dbf7c..a6dfb697d8c5a 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: 2022-09-20 +date: 2022-09-21 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 5ff9b1833cfb0..c281ebdbd88df 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: 2022-09-20 +date: 2022-09-21 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 63eab9d578d13..800fbabeaf203 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: 2022-09-20 +date: 2022-09-21 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 944b8314efe6d..f574152d0a191 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: 2022-09-20 +date: 2022-09-21 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 0971a99c4c319..625d6628b13cf 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: 2022-09-20 +date: 2022-09-21 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 2e9c36c73eb9a..6bd851dad3a56 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: 2022-09-20 +date: 2022-09-21 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 0c0d6e2b147ce..8c8bad65b3868 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: 2022-09-20 +date: 2022-09-21 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 990c37c3170ae..9037c2163f3d5 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: 2022-09-20 +date: 2022-09-21 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 d7a2655939277..69e98952c0f79 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: 2022-09-20 +date: 2022-09-21 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 d0388d1f5e605..7f049ea5d969d 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: 2022-09-20 +date: 2022-09-21 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 851682c10efa5..83c0958ab36ce 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: 2022-09-20 +date: 2022-09-21 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 de09fefa94f16..51b71c88e6a10 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json index 33b99385c989a..f4ce7d07d4c8f 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -7066,6 +7066,62 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.isAnnotationsLayer", + "type": "Function", + "tags": [], + "label": "isAnnotationsLayer", + "description": [], + "signature": [ + "(layer: Pick<", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.XYLayerConfig", + "text": "XYLayerConfig" + }, + ", \"layerType\">) => layer is ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.XYAnnotationsLayerConfig", + "text": "XYAnnotationsLayerConfig" + } + ], + "path": "src/plugins/visualizations/common/convert_to_lens/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.isAnnotationsLayer.$1", + "type": "Object", + "tags": [], + "label": "layer", + "description": [], + "signature": [ + "Pick<", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.XYLayerConfig", + "text": "XYLayerConfig" + }, + ", \"layerType\">" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.isVisDimension", @@ -7970,6 +8026,155 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig", + "type": "Interface", + "tags": [], + "label": "EventAnnotationConfig", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.filter", + "type": "CompoundType", + "tags": [], + "label": "filter", + "description": [], + "signature": [ + "{ type: \"kibana_query\"; } & ", + "Query" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.timeField", + "type": "string", + "tags": [], + "label": "timeField", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.extraFields", + "type": "Array", + "tags": [], + "label": "extraFields", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.label", + "type": "string", + "tags": [], + "label": "label", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.color", + "type": "string", + "tags": [], + "label": "color", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.isHidden", + "type": "CompoundType", + "tags": [], + "label": "isHidden", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.icon", + "type": "string", + "tags": [], + "label": "icon", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "\"query\"" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.EventAnnotationConfig.key", + "type": "Object", + "tags": [], + "label": "key", + "description": [], + "signature": [ + "{ type: \"point_in_time\"; }" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.Filter", @@ -9533,6 +9738,88 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.XYAnnotationsLayerConfig", + "type": "Interface", + "tags": [], + "label": "XYAnnotationsLayerConfig", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.XYAnnotationsLayerConfig.layerId", + "type": "string", + "tags": [], + "label": "layerId", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.XYAnnotationsLayerConfig.annotations", + "type": "Array", + "tags": [], + "label": "annotations", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.EventAnnotationConfig", + "text": "EventAnnotationConfig" + }, + "[]" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.XYAnnotationsLayerConfig.ignoreGlobalFilters", + "type": "boolean", + "tags": [], + "label": "ignoreGlobalFilters", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.XYAnnotationsLayerConfig.layerType", + "type": "string", + "tags": [], + "label": "layerType", + "description": [], + "signature": [ + "\"annotations\"" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.XYAnnotationsLayerConfig.indexPatternId", + "type": "string", + "tags": [], + "label": "indexPatternId", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.XYConfiguration", @@ -11742,6 +12029,14 @@ "docId": "kibVisualizationsPluginApi", "section": "def-common.XYReferenceLineLayerConfig", "text": "XYReferenceLineLayerConfig" + }, + " | ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.XYAnnotationsLayerConfig", + "text": "XYAnnotationsLayerConfig" } ], "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 86e1618717ea1..90b1267c266a9 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: 2022-09-20 +date: 2022-09-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 611 | 12 | 582 | 14 | +| 630 | 12 | 601 | 14 | ## Client From 2e2bc2c0695cf82a47b9c0302537da98a49b47d4 Mon Sep 17 00:00:00 2001 From: Brian McGue Date: Wed, 21 Sep 2022 00:22:22 -0700 Subject: [PATCH 32/55] [Enterprise Search 2793] Change model type on trained models (#141170) * Ordering of Object keys * Pipeline processor modelType to types Mimic the logic in x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx#fetchModelsData * Add key to flex item * Add default empty object In case inference_config is null --- .../common/types/pipelines.ts | 4 +-- .../inference_pipeline_card.test.tsx | 6 ++-- .../pipelines/inference_pipeline_card.tsx | 18 ++++++----- .../ml_inference_pipeline_processors_card.tsx | 2 +- .../search_index/pipelines/pipelines_logic.ts | 26 ++++++++-------- ...h_ml_inference_pipeline_processors.test.ts | 30 +++++++++++-------- .../fetch_ml_inference_pipeline_processors.ts | 11 +++++-- 7 files changed, 55 insertions(+), 42 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/types/pipelines.ts b/x-pack/plugins/enterprise_search/common/types/pipelines.ts index 9438ce5ef4bc1..f6b3141cf9833 100644 --- a/x-pack/plugins/enterprise_search/common/types/pipelines.ts +++ b/x-pack/plugins/enterprise_search/common/types/pipelines.ts @@ -6,8 +6,8 @@ */ export interface InferencePipeline { + isDeployed: boolean; pipelineName: string; trainedModelName: string; - isDeployed: boolean; - modelType: string; + types: string[]; } diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx index f329e0bf2b677..1c79cff0244e3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx @@ -16,15 +16,15 @@ import { EuiBadge, EuiHealth, EuiPanel, EuiTitle } from '@elastic/eui'; import { InferencePipelineCard } from './inference_pipeline_card'; export const DEFAULT_VALUES = { + isDeployed: true, pipelineName: 'Sample Processor', trainedModelName: 'example_trained_model', - isDeployed: true, - modelType: 'pytorch', + types: ['pytorch'], }; const mockValues = { ...DEFAULT_VALUES }; -describe('InfererencePipelineCard', () => { +describe('InferencePipelineCard', () => { beforeEach(() => { jest.clearAllMocks(); setMockValues(mockValues); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx index 270e2dc5d1714..e67cbdd9005c9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx @@ -37,7 +37,7 @@ export const InferencePipelineCard: React.FC = ({ pipelineName, trainedModelName, isDeployed, - modelType, + types, }) => { const { http } = useValues(HttpLogic); const { indexName } = useValues(IndexNameLogic); @@ -135,13 +135,15 @@ export const InferencePipelineCard: React.FC = ({ {deployedText}
)} - - - - {modelType} - - - + {types.map((type) => ( + + + + {type} + + + + ))}
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx index 0b8d7ec671753..ab90aa1d85464 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx @@ -36,7 +36,7 @@ export const MlInferencePipelineProcessorsCard: React.FC = () => { trainedModelName={item.trainedModelName} pipelineName={item.pipelineName} isDeployed={item.isDeployed} - modelType={item.modelType} + types={item.types} /> ))} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.ts index e0ca6574b63d6..e6cb840be420a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.ts @@ -59,8 +59,8 @@ type PipelinesActions = Pick< Actions, 'apiError' | 'apiSuccess' | 'makeRequest' > & { - closeModal: () => void; closeAddMlInferencePipelineModal: () => void; + closeModal: () => void; createCustomPipeline: Actions< CreateCustomPipelineApiLogicArgs, CreateCustomPipelineApiLogicResponse @@ -94,12 +94,12 @@ type PipelinesActions = Pick< fetchIndexApiSuccess: Actions['apiSuccess']; fetchMlInferenceProcessors: typeof FetchMlInferencePipelineProcessorsApiLogic.actions.makeRequest; fetchMlInferenceProcessorsApiError: (error: HttpError) => HttpError; + openAddMlInferencePipelineModal: () => void; openModal: () => void; savePipeline: () => void; setPipelineState(pipeline: IngestPipelineParams): { pipeline: IngestPipelineParams; }; - openAddMlInferencePipelineModal: () => void; }; interface PipelinesValues { @@ -110,16 +110,16 @@ interface PipelinesValues { index: FetchIndexApiResponse; mlInferencePipelineProcessors: InferencePipeline[]; pipelineState: IngestPipelineParams; - showModal: boolean; showAddMlInferencePipelineModal: boolean; + showModal: boolean; } export const PipelinesLogic = kea>({ actions: { - closeModal: true, closeAddMlInferencePipelineModal: true, - openModal: true, + closeModal: true, openAddMlInferencePipelineModal: true, + openModal: true, savePipeline: true, setPipelineState: (pipeline: IngestPipelineParams) => ({ pipeline }), }, @@ -267,20 +267,20 @@ export const PipelinesLogic = kea pipeline, }, ], - showModal: [ + showAddMlInferencePipelineModal: [ false, { - apiSuccess: () => false, - closeModal: () => false, - openModal: () => true, + closeAddMlInferencePipelineModal: () => false, + createMlInferencePipelineSuccess: () => false, + openAddMlInferencePipelineModal: () => true, }, ], - showAddMlInferencePipelineModal: [ + showModal: [ false, { - createMlInferencePipelineSuccess: () => false, - closeAddMlInferencePipelineModal: () => false, - openAddMlInferencePipelineModal: () => true, + apiSuccess: () => false, + closeModal: () => false, + openModal: () => true, }, ], }), diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts index 35bdbe0d64064..eb923a8f29852 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts @@ -42,8 +42,8 @@ const mockGetPipeline2 = { }, { inference: { - model_id: 'trained-model-id-1', inference_config: { regression: {} }, + model_id: 'trained-model-id-1', }, }, ], @@ -53,8 +53,8 @@ const mockGetPipeline2 = { processors: [ { inference: { - model_id: 'trained-model-id-2', inference_config: { regression: {} }, + model_id: 'trained-model-id-2', }, }, ], @@ -75,12 +75,16 @@ const mockGetTrainedModelsData = { count: 1, trained_model_configs: [ { + inference_config: { ner: {} }, model_id: 'trained-model-id-1', model_type: 'lang_ident', + tags: [], }, { + inference_config: { ner: {} }, model_id: 'trained-model-id-2', model_type: 'pytorch', + tags: [], }, ], }; @@ -92,26 +96,26 @@ const mockGetTrainedModelStats = { model_id: 'trained-model-id-1', }, { - model_id: 'trained-model-id-2', deployment_stats: { state: 'started', }, + model_id: 'trained-model-id-2', }, ], }; -const something = { +const trainedModelDataObject = { 'trained-model-id-1': { isDeployed: false, - modelType: 'lang_ident', pipelineName: 'ml-inference-pipeline-1', trainedModelName: 'trained-model-id-1', + types: ['lang_ident', 'ner'], }, 'trained-model-id-2': { isDeployed: true, - modelType: 'pytorch', pipelineName: 'ml-inference-pipeline-2', trainedModelName: 'trained-model-id-2', + types: ['pytorch', 'ner'], }, }; @@ -172,15 +176,15 @@ describe('fetchPipelineProcessorInferenceData lib function', () => { const expected = { 'trained-model-id-1': { isDeployed: false, - modelType: 'unknown', pipelineName: 'ml-inference-pipeline-1', trainedModelName: 'trained-model-id-1', + types: [], }, 'trained-model-id-2': { isDeployed: false, - modelType: 'unknown', pipelineName: 'ml-inference-pipeline-2', trainedModelName: 'trained-model-id-2', + types: [], }, }; @@ -219,19 +223,19 @@ describe('fetchAndAddTrainedModelData lib function', () => { const input = { 'trained-model-id-1': { isDeployed: false, - modelType: 'unknown', pipelineName: 'ml-inference-pipeline-1', trainedModelName: 'trained-model-id-1', + types: [], }, 'trained-model-id-2': { isDeployed: false, - modelType: 'unknown', pipelineName: 'ml-inference-pipeline-2', trainedModelName: 'trained-model-id-2', + types: [], }, } as Record; - const expected = something as Record; + const expected = trainedModelDataObject as Record; const response = await fetchAndAddTrainedModelData( mockClient as unknown as ElasticsearchClient, @@ -311,7 +315,7 @@ describe('fetchMlInferencePipelineProcessors lib function', () => { }); describe('when using an index that has an ml-inference pipeline', () => { - it('should return an empty array', async () => { + it('should return pipeline processor data for that pipeline', async () => { mockClient.ingest.getPipeline.mockImplementationOnce(() => Promise.resolve(mockGetPipeline)); mockClient.ingest.getPipeline.mockImplementationOnce(() => Promise.resolve({ 'ml-inference-pipeline-1': mockGetPipeline2['ml-inference-pipeline-1'] }) @@ -323,7 +327,7 @@ describe('fetchMlInferencePipelineProcessors lib function', () => { Promise.resolve(mockGetTrainedModelStats) ); - const expected = [something['trained-model-id-1']]; + const expected = [trainedModelDataObject['trained-model-id-1']] as InferencePipeline[]; const response = await fetchMlInferencePipelineProcessors( mockClient as unknown as ElasticsearchClient, diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts index 48e626ff1cecd..cfc80fc0f8b8b 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts @@ -6,6 +6,7 @@ */ import { ElasticsearchClient } from '@kbn/core/server'; +import { BUILT_IN_MODEL_TAG } from '@kbn/ml-plugin/common/constants/data_frame_analytics'; import { InferencePipeline } from '../../../common/types/pipelines'; import { getInferencePipelineNameFromIndexName } from '../../utils/ml_inference_pipeline_utils'; @@ -53,9 +54,9 @@ export const fetchPipelineProcessorInferenceData = async ( if (trainedModelName) pipelineProcessorData[trainedModelName] = { isDeployed: false, - modelType: 'unknown', pipelineName: pipelineProcessorName, trainedModelName, + types: [], }; return pipelineProcessorData; @@ -79,7 +80,13 @@ export const fetchAndAddTrainedModelData = async ( const trainedModelName = trainedModelData.model_id; if (pipelineProcessorData.hasOwnProperty(trainedModelName)) { - pipelineProcessorData[trainedModelName].modelType = trainedModelData.model_type || 'unknown'; + const isBuiltIn = trainedModelData.tags.includes(BUILT_IN_MODEL_TAG); + + pipelineProcessorData[trainedModelName].types = [ + trainedModelData.model_type, + ...Object.keys(trainedModelData.inference_config || {}), + ...(isBuiltIn ? [BUILT_IN_MODEL_TAG] : []), + ].filter((type): type is string => type !== undefined); } }); From 4118e2e42b4c5d1159c927971a9903f00f2a58bf Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 21 Sep 2022 09:59:39 +0200 Subject: [PATCH 33/55] fix fullscreen menu disappearing (#141128) --- .../lens/public/state_management/fullscreen_middleware.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/state_management/fullscreen_middleware.ts b/x-pack/plugins/lens/public/state_management/fullscreen_middleware.ts index f125a9e830ec9..e52c3d312802b 100644 --- a/x-pack/plugins/lens/public/state_management/fullscreen_middleware.ts +++ b/x-pack/plugins/lens/public/state_management/fullscreen_middleware.ts @@ -12,10 +12,10 @@ import { setToggleFullscreen } from './lens_slice'; /** cancels updates to the store that don't change the state */ export const fullscreenMiddleware = (storeDeps: LensStoreDeps) => (store: MiddlewareAPI) => { return (next: Dispatch) => (action: Action) => { - next(action); if (setToggleFullscreen.match(action)) { const isFullscreen = (store.getState as LensGetState)().lens.isFullscreenDatasource; - storeDeps.lensServices.chrome.setIsVisible(!isFullscreen); + storeDeps.lensServices.chrome.setIsVisible(Boolean(isFullscreen)); } + next(action); }; }; From 724ee2d74088bbc3d162c7a1c9963e6124628e6a Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 21 Sep 2022 11:11:39 +0200 Subject: [PATCH 34/55] Synthetics project update improvements (#140990) Co-authored-by: Dominique Clarke --- .../fleet/server/services/package_policy.ts | 87 ++++---- .../bulk_cruds/edit_monitor_bulk.ts | 132 +++++++++++++ .../routes/monitor_cruds/edit_monitor.test.ts | 13 +- .../routes/monitor_cruds/edit_monitor.ts | 9 +- .../synthetics_private_location.test.ts | 7 +- .../synthetics_private_location.ts | 185 ++++++++++-------- .../project_monitor_formatter.ts | 174 ++++++++-------- .../synthetics_monitor_client.test.ts | 19 +- .../synthetics_monitor_client.ts | 60 ++++-- .../synthetics_service/synthetics_service.ts | 6 +- .../apis/uptime/rest/add_monitor_project.ts | 16 +- 11 files changed, 457 insertions(+), 251 deletions(-) create mode 100644 x-pack/plugins/synthetics/server/routes/monitor_cruds/bulk_cruds/edit_monitor_bulk.ts diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index 4b4b9615009f3..77c5b67d9a782 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -566,59 +566,56 @@ class PackagePolicyClientImpl implements PackagePolicyClient { const packageInfos = await getPackageInfoForPackagePolicies(packagePolicyUpdates, soClient); await soClient.bulkUpdate( - await pMap( - packagePolicyUpdates, - async (packagePolicyUpdate) => { - const id = packagePolicyUpdate.id; - const packagePolicy = { ...packagePolicyUpdate, name: packagePolicyUpdate.name.trim() }; - const oldPackagePolicy = oldPackagePolicies.find((p) => p.id === id); - if (!oldPackagePolicy) { - throw new Error('Package policy not found'); - } + await pMap(packagePolicyUpdates, async (packagePolicyUpdate) => { + const id = packagePolicyUpdate.id; + const packagePolicy = { ...packagePolicyUpdate, name: packagePolicyUpdate.name.trim() }; + const oldPackagePolicy = oldPackagePolicies.find((p) => p.id === id); + if (!oldPackagePolicy) { + throw new Error('Package policy not found'); + } - const { version, ...restOfPackagePolicy } = packagePolicy; + // id and version are not part of the saved object attributes + const { version, id: _id, ...restOfPackagePolicy } = packagePolicy; - if (packagePolicyUpdate.is_managed && !options?.force) { - throw new PackagePolicyRestrictionRelatedError(`Cannot update package policy ${id}`); - } + if (packagePolicyUpdate.is_managed && !options?.force) { + throw new PackagePolicyRestrictionRelatedError(`Cannot update package policy ${id}`); + } - let inputs = restOfPackagePolicy.inputs.map((input) => - assignStreamIdToInput(oldPackagePolicy.id, input) + let inputs = restOfPackagePolicy.inputs.map((input) => + assignStreamIdToInput(oldPackagePolicy.id, input) + ); + + inputs = enforceFrozenInputs(oldPackagePolicy.inputs, inputs, options?.force); + let elasticsearch: PackagePolicy['elasticsearch']; + if (packagePolicy.package?.name) { + const pkgInfo = packageInfos.get( + `${packagePolicy.package.name}-${packagePolicy.package.version}` ); + if (pkgInfo) { + validatePackagePolicyOrThrow(packagePolicy, pkgInfo); - inputs = enforceFrozenInputs(oldPackagePolicy.inputs, inputs, options?.force); - let elasticsearch: PackagePolicy['elasticsearch']; - if (packagePolicy.package?.name) { - const pkgInfo = packageInfos.get( - `${packagePolicy.package.name}-${packagePolicy.package.version}` - ); - if (pkgInfo) { - validatePackagePolicyOrThrow(packagePolicy, pkgInfo); - - inputs = await _compilePackagePolicyInputs(pkgInfo, packagePolicy.vars || {}, inputs); - elasticsearch = pkgInfo.elasticsearch; - } + inputs = await _compilePackagePolicyInputs(pkgInfo, packagePolicy.vars || {}, inputs); + elasticsearch = pkgInfo.elasticsearch; } + } - // Handle component template/mappings updates for experimental features, e.g. synthetic source - await handleExperimentalDatastreamFeatureOptIn({ soClient, esClient, packagePolicy }); + // Handle component template/mappings updates for experimental features, e.g. synthetic source + await handleExperimentalDatastreamFeatureOptIn({ soClient, esClient, packagePolicy }); - return { - type: SAVED_OBJECT_TYPE, - id, - attributes: { - ...restOfPackagePolicy, - inputs, - elasticsearch, - revision: oldPackagePolicy.revision + 1, - updated_at: new Date().toISOString(), - updated_by: options?.user?.username ?? 'system', - }, - version, - }; - }, - { concurrency: 50 } - ) + return { + type: SAVED_OBJECT_TYPE, + id, + attributes: { + ...restOfPackagePolicy, + inputs, + elasticsearch, + revision: oldPackagePolicy.revision + 1, + updated_at: new Date().toISOString(), + updated_by: options?.user?.username ?? 'system', + }, + version, + }; + }) ); const agentPolicyIds = new Set(packagePolicyUpdates.map((p) => p.policy_id)); diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/bulk_cruds/edit_monitor_bulk.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/bulk_cruds/edit_monitor_bulk.ts new file mode 100644 index 0000000000000..5c28bdab9d3d1 --- /dev/null +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/bulk_cruds/edit_monitor_bulk.ts @@ -0,0 +1,132 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + SavedObjectsUpdateResponse, + SavedObject, + SavedObjectsClientContract, + KibanaRequest, +} from '@kbn/core/server'; +import { SyntheticsMonitorClient } from '../../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; +import { + MonitorFields, + EncryptedSyntheticsMonitor, + SyntheticsMonitorWithSecrets, + SyntheticsMonitor, + ConfigKey, + PrivateLocation, +} from '../../../../common/runtime_types'; +import { syntheticsMonitorType } from '../../../legacy_uptime/lib/saved_objects/synthetics_monitor'; +import { + sendTelemetryEvents, + formatTelemetryUpdateEvent, +} from '../../telemetry/monitor_upgrade_sender'; +import type { UptimeServerSetup } from '../../../legacy_uptime/lib/adapters/framework'; + +// Simplify return promise type and type it with runtime_types + +export const syncEditedMonitorBulk = async ({ + server, + request, + spaceId, + monitorsToUpdate, + savedObjectsClient, + privateLocations, + syntheticsMonitorClient, +}: { + monitorsToUpdate: Array<{ + normalizedMonitor: SyntheticsMonitor; + monitorWithRevision: SyntheticsMonitorWithSecrets; + previousMonitor: SavedObject; + decryptedPreviousMonitor: SavedObject; + }>; + server: UptimeServerSetup; + syntheticsMonitorClient: SyntheticsMonitorClient; + savedObjectsClient: SavedObjectsClientContract; + request: KibanaRequest; + privateLocations: PrivateLocation[]; + spaceId: string; +}) => { + let savedObjectsSuccessful = false; + let syncSuccessful = false; + + try { + async function updateSavedObjects() { + try { + const editedSOPromise = await savedObjectsClient.bulkUpdate( + monitorsToUpdate.map(({ previousMonitor, monitorWithRevision }) => ({ + type: syntheticsMonitorType, + id: previousMonitor.id, + attributes: monitorWithRevision, + })) + ); + savedObjectsSuccessful = true; + return editedSOPromise; + } catch (e) { + savedObjectsSuccessful = false; + } + } + + async function syncUpdatedMonitors() { + try { + const editSyncPromise = await syntheticsMonitorClient.editMonitors( + monitorsToUpdate.map(({ normalizedMonitor, previousMonitor }) => ({ + monitor: normalizedMonitor as MonitorFields, + id: previousMonitor.id, + previousMonitor, + })), + request, + savedObjectsClient, + privateLocations, + spaceId + ); + syncSuccessful = true; + return editSyncPromise; + } catch (e) { + syncSuccessful = false; + } + } + + const [editedMonitorSavedObjects, errors] = await Promise.all([ + updateSavedObjects(), + syncUpdatedMonitors(), + ]); + + monitorsToUpdate.forEach(({ normalizedMonitor, previousMonitor }) => { + const editedMonitorSavedObject = editedMonitorSavedObjects?.saved_objects.find( + (obj) => obj.id === previousMonitor.id + ); + + sendTelemetryEvents( + server.logger, + server.telemetry, + formatTelemetryUpdateEvent( + editedMonitorSavedObject as SavedObjectsUpdateResponse, + previousMonitor, + server.kibanaVersion, + Boolean((normalizedMonitor as MonitorFields)[ConfigKey.SOURCE_INLINE]), + errors + ) + ); + }); + + return { errors, editedMonitors: editedMonitorSavedObjects?.saved_objects }; + } catch (e) { + server.logger.error(`Unable to update Synthetics monitors `); + + if (!syncSuccessful && savedObjectsSuccessful) { + await savedObjectsClient.bulkUpdate( + monitorsToUpdate.map(({ previousMonitor, decryptedPreviousMonitor }) => ({ + type: syntheticsMonitorType, + id: previousMonitor.id, + attributes: decryptedPreviousMonitor.attributes, + })) + ); + } + + throw e; + } +}; diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.test.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.test.ts index d0cb2fe02d4fa..9f4492ce2dc70 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.test.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.test.ts @@ -49,6 +49,7 @@ describe('syncEditedMonitor', () => { }, packagePolicyService: { get: jest.fn().mockReturnValue({}), + getByIDs: jest.fn().mockReturnValue([]), buildPackagePolicyFromPackage: jest.fn().mockReturnValue({}), }, }, @@ -79,7 +80,9 @@ describe('syncEditedMonitor', () => { const previousMonitor = { id: 'saved-obj-id', - attributes: { name: editedMonitor.name }, + attributes: { name: editedMonitor.name, locations: [] } as any, + type: 'synthetics-monitor', + references: [], } as SavedObject; const syntheticsService = new SyntheticsService(serverMock); @@ -104,9 +107,11 @@ describe('syncEditedMonitor', () => { }); expect(syntheticsService.editConfig).toHaveBeenCalledWith( - expect.objectContaining({ - id: 'saved-obj-id', - }) + expect.arrayContaining([ + expect.objectContaining({ + id: 'saved-obj-id', + }), + ]) ); expect(serverMock.authSavedObjectsClient?.update).toHaveBeenCalledWith( diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts index 5dc77816f4aa3..a16a1ba7089e5 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/edit_monitor.ts @@ -13,6 +13,7 @@ import { KibanaRequest, } from '@kbn/core/server'; import { SavedObjectsErrorHelpers } from '@kbn/core/server'; +import { getSyntheticsPrivateLocations } from '../../legacy_uptime/lib/saved_objects/private_locations'; import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; import { MonitorFields, @@ -153,11 +154,13 @@ export const syncEditedMonitor = async ({ monitorWithRevision ); - const editSyncPromise = syntheticsMonitorClient.editMonitor( - normalizedMonitor as MonitorFields, - previousMonitor.id, + const allPrivateLocations = await getSyntheticsPrivateLocations(savedObjectsClient); + + const editSyncPromise = syntheticsMonitorClient.editMonitors( + [{ monitor: normalizedMonitor as MonitorFields, id: previousMonitor.id, previousMonitor }], request, savedObjectsClient, + allPrivateLocations, spaceId ); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.test.ts index e8a012f6cf23a..8dc6688a70f3f 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.test.ts @@ -123,7 +123,7 @@ describe('SyntheticsPrivateLocation', () => { [true, 'Unable to create Synthetics package policy for private location'], [ false, - 'Unable to update Synthetics package policy for monitor Test Monitor. Fleet write permissions are needed to use Synthetics private locations.', + 'Unable to update Synthetics package policy for monitor. Fleet write permissions are needed to use Synthetics private locations.', ], ])('throws errors for edit monitor', async (writeIntegrationPolicies, error) => { const syntheticsPrivateLocation = new SyntheticsPrivateLocation({ @@ -137,10 +137,11 @@ describe('SyntheticsPrivateLocation', () => { }); try { - await syntheticsPrivateLocation.editMonitor( - testConfig, + await syntheticsPrivateLocation.editMonitors( + [testConfig], {} as unknown as KibanaRequest, savedObjectsClientMock, + [mockPrivateLocation], 'test-space' ); } catch (e) { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts b/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts index c694f2aa7567e..f51f9e479929e 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/private_location/synthetics_private_location.ts @@ -43,13 +43,13 @@ export class SyntheticsPrivateLocation { return `${config.id}-${locId}-${spaceId}`; } - async generateNewPolicy( + generateNewPolicy( config: HeartbeatConfig, privateLocation: PrivateLocation, savedObjectsClient: SavedObjectsClientContract, newPolicyTemplate: NewPackagePolicy, spaceId: string - ): Promise { + ): NewPackagePolicy | null { if (!savedObjectsClient) { throw new Error('Could not find savedObjectsClient'); } @@ -128,7 +128,7 @@ export class SyntheticsPrivateLocation { ); } - const newPolicy = await this.generateNewPolicy( + const newPolicy = this.generateNewPolicy( config, location, savedObjectsClient, @@ -163,83 +163,106 @@ export class SyntheticsPrivateLocation { } } - async editMonitor( - config: HeartbeatConfig, + async editMonitors( + configs: HeartbeatConfig[], request: KibanaRequest, savedObjectsClient: SavedObjectsClientContract, + allPrivateLocations: PrivateLocation[], spaceId: string ) { await this.checkPermissions( request, - `Unable to update Synthetics package policy for monitor ${ - config[ConfigKey.NAME] - }. Fleet write permissions are needed to use Synthetics private locations.` + `Unable to update Synthetics package policy for monitor. Fleet write permissions are needed to use Synthetics private locations.` ); - const { locations } = config; - - const allPrivateLocations = await getSyntheticsPrivateLocations(savedObjectsClient); - const newPolicyTemplate = await this.buildNewPolicy(savedObjectsClient); if (!newPolicyTemplate) { throw new Error(`Unable to create Synthetics package policy for private location`); } - const monitorPrivateLocations = locations.filter((loc) => !loc.isServiceManaged); + const policiesToUpdate: Array = []; + const policiesToCreate: NewPackagePolicyWithId[] = []; + const policiesToDelete: string[] = []; - for (const privateLocation of allPrivateLocations) { - const hasLocation = monitorPrivateLocations?.some((loc) => loc.id === privateLocation.id); - const currId = this.getPolicyId(config, privateLocation, spaceId); - const hasPolicy = await this.getMonitor(currId, savedObjectsClient); - try { - if (hasLocation) { - const newPolicy = await this.generateNewPolicy( - config, - privateLocation, - savedObjectsClient, - newPolicyTemplate, - spaceId - ); + const existingPolicies = await this.getExistingPolicies( + configs, + allPrivateLocations, + savedObjectsClient, + spaceId + ); - if (!newPolicy) { - throw new Error( - `Unable to ${ - hasPolicy ? 'update' : 'create' - } Synthetics package policy for private location ${privateLocation.label}` + for (const config of configs) { + const { locations } = config; + + const monitorPrivateLocations = locations.filter((loc) => !loc.isServiceManaged); + + for (const privateLocation of allPrivateLocations) { + const hasLocation = monitorPrivateLocations?.some((loc) => loc.id === privateLocation.id); + const currId = this.getPolicyId(config, privateLocation, spaceId); + const hasPolicy = existingPolicies?.some((policy) => policy.id === currId); + try { + if (hasLocation) { + const newPolicy = this.generateNewPolicy( + config, + privateLocation, + savedObjectsClient, + newPolicyTemplate, + spaceId ); - } - if (hasPolicy) { - await this.updatePolicy(newPolicy, currId, savedObjectsClient); - } else { - await this.createPolicy(newPolicy, currId, savedObjectsClient); - } - } else if (hasPolicy) { - const soClient = savedObjectsClient; - const esClient = this.server.uptimeEsClient.baseESClient; - try { - await this.server.fleet.packagePolicyService.delete(soClient, esClient, [currId], { - force: true, - }); - } catch (e) { - this.server.logger.error(e); - throw new Error( - `Unable to delete Synthetics package policy for monitor ${ - config[ConfigKey.NAME] - } with private location ${privateLocation.label}` - ); + if (!newPolicy) { + throw new Error( + `Unable to ${ + hasPolicy ? 'update' : 'create' + } Synthetics package policy for private location ${privateLocation.label}` + ); + } + + if (hasPolicy) { + policiesToUpdate.push({ ...newPolicy, id: currId }); + } else { + policiesToCreate.push({ ...newPolicy, id: currId }); + } + } else if (hasPolicy) { + policiesToDelete.push(currId); } + } catch (e) { + this.server.logger.error(e); + throw new Error( + `Unable to ${hasPolicy ? 'update' : 'create'} Synthetics package policy for monitor ${ + config[ConfigKey.NAME] + } with private location ${privateLocation.label}` + ); } - } catch (e) { - this.server.logger.error(e); - throw new Error( - `Unable to ${hasPolicy ? 'update' : 'create'} Synthetics package policy for monitor ${ - config[ConfigKey.NAME] - } with private location ${privateLocation.label}` - ); } } + + await Promise.all([ + this.createPolicyBulk(policiesToCreate, savedObjectsClient), + this.updatePolicyBulk(policiesToUpdate, savedObjectsClient), + this.deletePolicyBulk(policiesToDelete, savedObjectsClient), + ]); + } + + async getExistingPolicies( + configs: HeartbeatConfig[], + allPrivateLocations: PrivateLocation[], + savedObjectsClient: SavedObjectsClientContract, + spaceId: string + ) { + const listOfPolicies: string[] = []; + for (const config of configs) { + for (const privateLocation of allPrivateLocations) { + const currId = this.getPolicyId(config, privateLocation, spaceId); + listOfPolicies.push(currId); + } + } + return ( + (await this.server.fleet.packagePolicyService.getByIDs(savedObjectsClient, listOfPolicies, { + ignoreMissing: true, + })) ?? [] + ); } async createPolicyBulk( @@ -248,7 +271,7 @@ export class SyntheticsPrivateLocation { ) { const soClient = savedObjectsClient; const esClient = this.server.uptimeEsClient.baseESClient; - if (soClient && esClient) { + if (soClient && esClient && newPolicies.length > 0) { return await this.server.fleet.packagePolicyService.bulkCreate( soClient, esClient, @@ -257,34 +280,35 @@ export class SyntheticsPrivateLocation { } } - async createPolicy( - newPolicy: NewPackagePolicy, - id: string, + async updatePolicyBulk( + updatedPolicies: Array, savedObjectsClient: SavedObjectsClientContract ) { const soClient = savedObjectsClient; const esClient = this.server.uptimeEsClient.baseESClient; - if (soClient && esClient) { - return await this.server.fleet.packagePolicyService.create(soClient, esClient, newPolicy, { - id, - overwrite: true, - }); + if (soClient && esClient && updatedPolicies.length > 0) { + return await this.server.fleet.packagePolicyService.bulkUpdate( + soClient, + esClient, + updatedPolicies, + { + force: true, + } + ); } } - async updatePolicy( - updatedPolicy: NewPackagePolicy, - id: string, + async deletePolicyBulk( + policyIdsToDelete: string[], savedObjectsClient: SavedObjectsClientContract ) { const soClient = savedObjectsClient; const esClient = this.server.uptimeEsClient.baseESClient; - if (soClient && esClient) { - return await this.server.fleet.packagePolicyService.update( + if (soClient && esClient && policyIdsToDelete.length > 0) { + return await this.server.fleet.packagePolicyService.delete( soClient, esClient, - id, - updatedPolicy, + policyIdsToDelete, { force: true, } @@ -292,15 +316,6 @@ export class SyntheticsPrivateLocation { } } - async getMonitor(id: string, savedObjectsClient: SavedObjectsClientContract) { - try { - return await this.server.fleet.packagePolicyService.get(savedObjectsClient!, id); - } catch (e) { - this.server.logger.debug(e); - return null; - } - } - async deleteMonitors( configs: HeartbeatConfig[], request: KibanaRequest, @@ -346,9 +361,7 @@ export class SyntheticsPrivateLocation { request, `Unable to delete Synthetics package policy for monitor. Fleet write permissions are needed to use Synthetics private locations.` ); - await this.server.fleet.packagePolicyService.delete(soClient, esClient, policyIdsToDelete, { - force: true, - }); + await this.deletePolicyBulk(policyIdsToDelete, savedObjectsClient); } } } diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts index 744003d16ea3f..aa0be87f0e818 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts @@ -12,10 +12,12 @@ import { SavedObjectsClientContract, SavedObjectsFindResult, } from '@kbn/core/server'; +import pMap from 'p-map'; import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; import { syncNewMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/add_monitor_bulk'; import { deleteMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/delete_monitor_bulk'; import { SyntheticsMonitorClient } from '../synthetics_monitor/synthetics_monitor_client'; +import { syncEditedMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/edit_monitor_bulk'; import { BrowserFields, ConfigKey, @@ -32,9 +34,8 @@ import { syntheticsMonitorType, syntheticsMonitor, } from '../../legacy_uptime/lib/saved_objects/synthetics_monitor'; -import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; +import type { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; import { formatSecrets, normalizeSecrets } from '../utils/secrets'; -import { syncEditedMonitor } from '../../routes/monitor_cruds/edit_monitor'; import { validateProjectMonitor, validateMonitor, @@ -121,11 +122,13 @@ export class ProjectMonitorFormatter { public configureAllProjectMonitors = async () => { const existingMonitors = await this.getProjectMonitorsForProject(); - this.staleMonitorsMap = await this.getStaleMonitorsMap(existingMonitors); const normalizedNewMonitors: BrowserFields[] = []; - const normalizedUpdateMonitors: BrowserFields[] = []; + const normalizedUpdateMonitors: Array<{ + previousMonitor: SavedObjectsFindResult; + monitor: BrowserFields; + }> = []; for (const monitor of this.monitors) { const previousMonitor = existingMonitors.find( @@ -142,7 +145,7 @@ export class ProjectMonitorFormatter { if (this.staleMonitorsMap[monitor.id]) { this.staleMonitorsMap[monitor.id].stale = false; } - normalizedUpdateMonitors.push(normM as MonitorFields); + normalizedUpdateMonitors.push({ monitor: normM as MonitorFields, previousMonitor }); } else { normalizedNewMonitors.push(normM as MonitorFields); } @@ -151,7 +154,26 @@ export class ProjectMonitorFormatter { await this.createMonitorsBulk(normalizedNewMonitors); - await this.updateMonitorBulk(normalizedUpdateMonitors); + const { updatedCount } = await this.updateMonitors(normalizedUpdateMonitors); + + if (normalizedUpdateMonitors.length > 0) { + let updateMessage = ''; + if (updatedCount > 0) { + updateMessage = `${updatedCount} monitor${ + updatedCount > 1 ? 's' : '' + } updated successfully.`; + } + + const noChanges = normalizedUpdateMonitors.length - updatedCount; + let noChangeMessage = ''; + if (noChanges > 0) { + noChangeMessage = `${noChanges} monitor${noChanges > 1 ? 's' : ''} found with no changes.`; + } + + this.handleStreamingMessage({ + message: `${updateMessage} ${noChangeMessage}`, + }); + } await this.handleStaleMonitors(); }; @@ -274,19 +296,6 @@ export class ProjectMonitorFormatter { return hits; }; - private getExistingMonitor = async ( - journeyId: string - ): Promise> => { - const filter = `${this.projectFilter} AND ${syntheticsMonitorType}.attributes.${ConfigKey.JOURNEY_ID}: "${journeyId}"`; - const { saved_objects: savedObjects } = - await this.savedObjectsClient.find({ - type: syntheticsMonitorType, - perPage: 1, - filter, - }); - return savedObjects?.[0]; - }; - private createMonitorsBulk = async (monitors: BrowserFields[]) => { try { if (monitors.length > 0) { @@ -331,75 +340,78 @@ export class ProjectMonitorFormatter { } }; - private updateMonitorBulk = async (monitors: BrowserFields[]) => { - try { - for (const monitor of monitors) { - const previousMonitor = await this.getExistingMonitor(monitor[ConfigKey.JOURNEY_ID]!); - await this.updateMonitor(previousMonitor, monitor as MonitorFields); - } - - if (monitors.length > 0) { - this.handleStreamingMessage({ - message: `${monitors.length} monitor${ - monitors.length > 1 ? 's' : '' - } updated successfully.`, - }); - } - } catch (e) { - this.server.logger.error(e); - this.failedMonitors.push({ - reason: 'Failed to update monitors', - details: e.message, - payload: monitors, - }); - this.handleStreamingMessage({ - message: `Failed to update ${monitors.length} monitors`, - }); - } + private getDecryptedMonitors = async ( + monitors: Array> + ) => { + return await pMap( + monitors, + async (monitor) => + this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( + syntheticsMonitor.name, + monitor.id, + { + namespace: monitor.namespaces?.[0], + } + ), + { concurrency: 500 } + ); }; - private updateMonitor = async ( - previousMonitor: SavedObjectsFindResult, - normalizedMonitor: MonitorFields + private updateMonitors = async ( + monitors: Array<{ + monitor: BrowserFields; + previousMonitor: SavedObjectsFindResult; + }> ): Promise<{ - editedMonitor: SavedObjectsUpdateResponse; + editedMonitors: Array>; errors: ServiceLocationErrors; + updatedCount: number; }> => { - const decryptedPreviousMonitor = - await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( - syntheticsMonitor.name, - previousMonitor.id, - { - namespace: previousMonitor.namespaces?.[0], - } - ); - const { - attributes: { [ConfigKey.REVISION]: _, ...normalizedPreviousMonitorAttributes }, - } = normalizeSecrets(decryptedPreviousMonitor); - const hasMonitorBeenEdited = !isEqual(normalizedMonitor, normalizedPreviousMonitorAttributes); - - if (hasMonitorBeenEdited) { - const monitorWithRevision = formatSecrets({ - ...normalizedPreviousMonitorAttributes, - ...normalizedMonitor, - revision: (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1, - }); - - const { editedMonitor } = await syncEditedMonitor({ - normalizedMonitor, - monitorWithRevision, - previousMonitor, - decryptedPreviousMonitor, - server: this.server, - syntheticsMonitorClient: this.syntheticsMonitorClient, - savedObjectsClient: this.savedObjectsClient, - request: this.request, - spaceId: this.spaceId, - }); - return { editedMonitor, errors: [] }; + const decryptedPreviousMonitors = await this.getDecryptedMonitors( + monitors.map((m) => m.previousMonitor) + ); + + const monitorsToUpdate = []; + + for (let i = 0; i < decryptedPreviousMonitors.length; i++) { + const decryptedPreviousMonitor = decryptedPreviousMonitors[i]; + const previousMonitor = monitors[i].previousMonitor; + const normalizedMonitor = monitors[i].monitor; + + const { + attributes: { [ConfigKey.REVISION]: _, ...normalizedPreviousMonitorAttributes }, + } = normalizeSecrets(decryptedPreviousMonitor); + const hasMonitorBeenEdited = !isEqual(normalizedMonitor, normalizedPreviousMonitorAttributes); + + if (hasMonitorBeenEdited) { + const monitorWithRevision = formatSecrets({ + ...normalizedPreviousMonitorAttributes, + ...normalizedMonitor, + revision: (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1, + }); + monitorsToUpdate.push({ + normalizedMonitor, + previousMonitor, + monitorWithRevision, + decryptedPreviousMonitor, + }); + } } - return { errors: [], editedMonitor: decryptedPreviousMonitor }; + const { editedMonitors } = await syncEditedMonitorBulk({ + monitorsToUpdate, + server: this.server, + syntheticsMonitorClient: this.syntheticsMonitorClient, + savedObjectsClient: this.savedObjectsClient, + request: this.request, + privateLocations: this.privateLocations, + spaceId: this.spaceId, + }); + return { + editedMonitors: editedMonitors ?? [], + errors: [], + updatedCount: monitorsToUpdate.length, + }; }; private handleStaleMonitors = async () => { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.test.ts index 10aa461a50d4c..21f0e68588c73 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.test.ts @@ -121,12 +121,23 @@ describe('SyntheticsMonitorClient', () => { const id = 'test-id-1'; const client = new SyntheticsMonitorClient(syntheticsService, serverMock); - client.privateLocationAPI.editMonitor = jest.fn(); - - await client.editMonitor(monitor, id, mockRequest, savedObjectsClientMock, 'test-space'); + client.privateLocationAPI.editMonitors = jest.fn(); + + await client.editMonitors( + [ + { + monitor, + id, + }, + ], + mockRequest, + savedObjectsClientMock, + privateLocations, + 'test-space' + ); expect(syntheticsService.editConfig).toHaveBeenCalledTimes(1); - expect(client.privateLocationAPI.editMonitor).toHaveBeenCalledTimes(1); + expect(client.privateLocationAPI.editMonitors).toHaveBeenCalledTimes(1); }); it('should delete a monitor', async () => { diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts index 53d5f2f592043..8af7fca704ab0 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_monitor/synthetics_monitor_client.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { KibanaRequest, SavedObjectsClientContract } from '@kbn/core/server'; +import { KibanaRequest, SavedObject, SavedObjectsClientContract } from '@kbn/core/server'; import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; import { SyntheticsPrivateLocation } from '../private_location/synthetics_private_location'; import { SyntheticsService } from '../synthetics_service'; @@ -15,6 +15,7 @@ import { SyntheticsMonitorWithId, HeartbeatConfig, PrivateLocation, + EncryptedSyntheticsMonitor, } from '../../../common/runtime_types'; export class SyntheticsMonitorClient { @@ -76,30 +77,48 @@ export class SyntheticsMonitorClient { return { newPolicies, syncErrors }; } - async editMonitor( - editedMonitor: MonitorFields, - id: string, + async editMonitors( + monitors: Array<{ + monitor: MonitorFields; + id: string; + previousMonitor?: SavedObject; + }>, request: KibanaRequest, savedObjectsClient: SavedObjectsClientContract, + allPrivateLocations: PrivateLocation[], spaceId: string ) { - const editedConfig = formatHeartbeatRequest({ - monitor: editedMonitor, - monitorId: id, - customHeartbeatId: (editedMonitor as MonitorFields)[ConfigKey.CUSTOM_HEARTBEAT_ID], - }); - - const { publicLocations } = this.parseLocations(editedConfig); + const privateConfigs: HeartbeatConfig[] = []; + const publicConfigs: HeartbeatConfig[] = []; - await this.privateLocationAPI.editMonitor(editedConfig, request, savedObjectsClient, spaceId); + for (const editedMonitor of monitors) { + const editedConfig = formatHeartbeatRequest({ + monitor: editedMonitor.monitor, + monitorId: editedMonitor.id, + customHeartbeatId: (editedMonitor.monitor as MonitorFields)[ConfigKey.CUSTOM_HEARTBEAT_ID], + }); + const { publicLocations, privateLocations } = this.parseLocations(editedConfig); + if (publicLocations.length > 0) { + publicConfigs.push(editedConfig); + } - if (publicLocations.length > 0) { - return await this.syntheticsService.editConfig(editedConfig); + if (privateLocations.length > 0 || this.hasPrivateLocations(editedMonitor.previousMonitor)) { + privateConfigs.push(editedConfig); + } } - await this.syntheticsService.editConfig(editedConfig); - } + await this.privateLocationAPI.editMonitors( + privateConfigs, + request, + savedObjectsClient, + allPrivateLocations, + spaceId + ); + if (publicConfigs.length > 0) { + return await this.syntheticsService.editConfig(publicConfigs); + } + } async deleteMonitors( monitors: SyntheticsMonitorWithId[], request: KibanaRequest, @@ -119,6 +138,15 @@ export class SyntheticsMonitorClient { return pubicResponse; } + hasPrivateLocations(previousMonitor?: SavedObject) { + if (!previousMonitor) { + return false; + } + const { locations } = previousMonitor.attributes; + + return locations.some((loc) => !loc.isServiceManaged); + } + parseLocations(config: HeartbeatConfig) { const { locations } = config; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index 6c815e5a2cbdf..d0211800dc6c0 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -282,8 +282,10 @@ export class SyntheticsService { } } - async editConfig(monitorConfig: HeartbeatConfig) { - const monitors = this.formatConfigs([monitorConfig]); + async editConfig(monitorConfig: HeartbeatConfig | HeartbeatConfig[]) { + const monitors = this.formatConfigs( + Array.isArray(monitorConfig) ? monitorConfig : [monitorConfig] + ); this.apiKey = await this.getApiKey(); diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts index 3c5442d6fdc90..1110bbb875c73 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts @@ -394,7 +394,7 @@ export default function ({ getService }: FtrProviderContext) { ); expect(messages).to.have.length(2); - expect(messages[0]).eql('1 monitor updated successfully.'); + expect(messages[0]).eql(' 1 monitor found with no changes.'); expect(messages[1].createdMonitors).eql([]); expect(messages[1].failedMonitors).eql([]); expect(messages[1].updatedMonitors).eql( @@ -458,10 +458,10 @@ export default function ({ getService }: FtrProviderContext) { })), }; - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) - .set('kbn-xsrf', 'true') - .send(editedMonitors); + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(editedMonitors) + ); const updatedMonitorsResponse = await Promise.all( projectMonitors.monitors.map((monitor) => { @@ -476,6 +476,7 @@ export default function ({ getService }: FtrProviderContext) { updatedMonitorsResponse.forEach((response) => { expect(response.body.monitors[0].attributes.revision).eql(2); }); + expect(messages[0]).eql('1 monitor updated successfully. '); } finally { await Promise.all([ projectMonitors.monitors.map((monitor) => { @@ -504,7 +505,7 @@ export default function ({ getService }: FtrProviderContext) { ); expect(messages).to.have.length(2); - expect(messages[0]).eql('1 monitor updated successfully.'); + expect(messages[0]).eql(' 1 monitor found with no changes.'); expect(messages[1].createdMonitors).eql([]); expect(messages[1].failedMonitors).eql([]); expect(messages[1].deletedMonitors).eql([]); @@ -566,6 +567,7 @@ export default function ({ getService }: FtrProviderContext) { const { monitors } = getResponse.body; expect(monitors[0]).eql(undefined); + expect(messages[0]).eql(` 1 monitor found with no changes.`); expect(messages[1]).eql(`Monitor ${secondMonitor.id} deleted successfully`); expect(messages[2].createdMonitors).eql([]); expect(messages[2].failedMonitors).eql([]); @@ -922,7 +924,7 @@ export default function ({ getService }: FtrProviderContext) { JSON.stringify(projectMonitors) ); expect(messages).to.have.length(2); - expect(messages[0]).eql('1 monitor updated successfully.'); + expect(messages[0]).eql('1 monitor updated successfully. '); expect(messages[1].updatedMonitors).eql([projectMonitors.monitors[0].id]); // ensure that monitor can still be decrypted From 806dfabb0ab4b488546d40743827ebac6bce75a1 Mon Sep 17 00:00:00 2001 From: Katerina Patticha Date: Wed, 21 Sep 2022 11:12:52 +0200 Subject: [PATCH 35/55] [APM] Move service metric config to kibana advanced settings (#141147) * [APM] Move service metric config to kibana advanced settings * Add apmEnableServiceMetrics usage collector --- docs/settings/apm-settings.asciidoc | 3 - .../server/collectors/management/schema.ts | 4 + .../server/collectors/management/types.ts | 1 + src/plugins/telemetry/schema/oss_plugins.json | 8 +- x-pack/plugins/apm/server/index.ts | 3 - .../get_service_inventory_search_source.ts | 10 +- ...get_has_aggregated_service_metrics.test.ts | 124 ------------------ .../lib/helpers/service_metrics/index.ts | 7 +- .../apm/server/routes/services/route.ts | 13 ++ x-pack/plugins/observability/common/index.ts | 1 + .../observability/common/ui_settings_keys.ts | 1 + .../observability/server/ui_settings.ts | 16 +++ 12 files changed, 53 insertions(+), 138 deletions(-) delete mode 100644 x-pack/plugins/apm/server/lib/helpers/service_metrics/get_has_aggregated_service_metrics.test.ts diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc index fba7a32e17f1b..de5e8c686c61b 100644 --- a/docs/settings/apm-settings.asciidoc +++ b/docs/settings/apm-settings.asciidoc @@ -77,9 +77,6 @@ Maximum number of child items displayed when viewing trace details. Defaults to `xpack.observability.annotations.index` {ess-icon}:: Index name where Observability annotations are stored. Defaults to `observability-annotations`. -`xpack.apm.searchAggregatedServiceMetrics` {ess-icon}:: - Enables Service metrics. Defaults to `false`. When set to `true`, additional configuration in APM Server is required. - `xpack.apm.searchAggregatedTransactions` {ess-icon}:: Enables Transaction histogram metrics. Defaults to `auto` so the UI will use metric indices over transaction indices for transactions if aggregated transactions are found. When set to `always`, additional configuration in APM Server is required. When set to `never` and aggregated transactions are not used. + diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index cc80adc4cb463..d8511298f6ac9 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -438,6 +438,10 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, + 'observability:apmEnableServiceMetrics': { + type: 'boolean', + _meta: { description: 'Non-default value of setting.' }, + }, 'banners:placement': { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 924649351d988..7ca9ddfeef5b9 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -42,6 +42,7 @@ export interface UsageStats { 'observability:maxSuggestions': number; 'observability:enableComparisonByDefault': boolean; 'observability:enableServiceGroups': boolean; + 'observability:apmEnableServiceMetrics': boolean; 'observability:enableInfrastructureHostsView': boolean; 'visualize:enableLabs': boolean; 'visualization:heatmap:maxBuckets': number; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index a1ddc4ee56040..0a4d6c347674d 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -8702,6 +8702,12 @@ "description": "Non-default value of setting." } }, + "observability:apmEnableServiceMetrics": { + "type": "boolean", + "_meta": { + "description": "Non-default value of setting." + } + }, "banners:placement": { "type": "keyword", "_meta": { @@ -10323,4 +10329,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts index 7f2f7d208d896..6071c455ad84e 100644 --- a/x-pack/plugins/apm/server/index.ts +++ b/x-pack/plugins/apm/server/index.ts @@ -31,9 +31,6 @@ const configSchema = schema.object({ transactionGroupBucketSize: schema.number({ defaultValue: 1000 }), maxTraceItems: schema.number({ defaultValue: 1000 }), }), - searchAggregatedServiceMetrics: schema.boolean({ - defaultValue: false, - }), searchAggregatedTransactions: schema.oneOf( [ schema.literal(SearchAggregatedTransactionSetting.auto), diff --git a/x-pack/plugins/apm/server/lib/helpers/get_service_inventory_search_source.ts b/x-pack/plugins/apm/server/lib/helpers/get_service_inventory_search_source.ts index c668eda669e29..459eddfbdcc1f 100644 --- a/x-pack/plugins/apm/server/lib/helpers/get_service_inventory_search_source.ts +++ b/x-pack/plugins/apm/server/lib/helpers/get_service_inventory_search_source.ts @@ -11,11 +11,13 @@ import { APMConfig } from '../..'; export async function getServiceInventorySearchSource({ config, + serviceMetricsEnabled, apmEventClient, start, end, kuery, }: { + serviceMetricsEnabled: boolean; config: APMConfig; apmEventClient: APMEventClient; start: number; @@ -26,7 +28,6 @@ export async function getServiceInventorySearchSource({ searchAggregatedServiceMetrics: boolean; }> { const commonProps = { - config, apmEventClient, kuery, start, @@ -34,8 +35,11 @@ export async function getServiceInventorySearchSource({ }; const [searchAggregatedTransactions, searchAggregatedServiceMetrics] = await Promise.all([ - getSearchAggregatedTransactions(commonProps), - getSearchAggregatedServiceMetrics(commonProps), + getSearchAggregatedTransactions({ ...commonProps, config }), + getSearchAggregatedServiceMetrics({ + ...commonProps, + serviceMetricsEnabled, + }), ]); return { diff --git a/x-pack/plugins/apm/server/lib/helpers/service_metrics/get_has_aggregated_service_metrics.test.ts b/x-pack/plugins/apm/server/lib/helpers/service_metrics/get_has_aggregated_service_metrics.test.ts deleted file mode 100644 index d78190d56e20a..0000000000000 --- a/x-pack/plugins/apm/server/lib/helpers/service_metrics/get_has_aggregated_service_metrics.test.ts +++ /dev/null @@ -1,124 +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 { getSearchAggregatedServiceMetrics } from '.'; -import { - SearchParamsMock, - inspectSearchParams, -} from '../../../utils/test_helpers'; -import { Setup } from '../setup_request'; - -const mockResponseWithServiceMetricsHits = { - took: 398, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - total: { - value: 1, - relation: 'gte' as const, - }, - hits: [], - }, -}; - -const mockResponseWithServiceMetricsNoHits = { - took: 398, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - total: { - value: 0, - relation: 'gte' as const, - }, - hits: [], - }, -}; - -describe('get default configuration for aggregated service metrics', () => { - it('should be false by default', async () => { - const mockSetup = { - apmEventClient: { search: () => Promise.resolve(response) }, - config: {}, - } as unknown as Setup; - - const response = await getSearchAggregatedServiceMetrics({ - apmEventClient: mockSetup.apmEventClient, - config: mockSetup.config, - kuery: '', - }); - expect(response).toBeFalsy(); - }); -}); - -describe('get has aggregated', () => { - it('should be false when xpack.apm.searchAggregatedServiceMetrics=false ', async () => { - const mockSetup = { - apmEventClient: { search: () => Promise.resolve(response) }, - config: { 'xpack.apm.searchAggregatedServiceMetrics': false }, - } as unknown as Setup; - - const response = await getSearchAggregatedServiceMetrics({ - apmEventClient: mockSetup.apmEventClient, - config: mockSetup.config, - kuery: '', - }); - expect(response).toBeFalsy(); - }); - - describe('with xpack.apm.searchAggregatedServiceMetrics=true', () => { - let mock: SearchParamsMock; - - const config = { - searchAggregatedServiceMetrics: true, - }; - - afterEach(() => { - mock.teardown(); - }); - it('should be true when service metrics data are found', async () => { - mock = await inspectSearchParams( - (setup) => - getSearchAggregatedServiceMetrics({ - apmEventClient: setup.apmEventClient, - config: setup.config, - kuery: '', - }), - { - config, - mockResponse: () => mockResponseWithServiceMetricsHits, - } - ); - expect(mock.response).toBeTruthy(); - }); - - it('should be false when service metrics data are not found', async () => { - mock = await inspectSearchParams( - (setup) => - getSearchAggregatedServiceMetrics({ - apmEventClient: setup.apmEventClient, - config: setup.config, - kuery: '', - }), - { - config, - mockResponse: () => mockResponseWithServiceMetricsNoHits, - } - ); - expect(mock.response).toBeFalsy(); - }); - }); -}); diff --git a/x-pack/plugins/apm/server/lib/helpers/service_metrics/index.ts b/x-pack/plugins/apm/server/lib/helpers/service_metrics/index.ts index fd449734e9772..175267bdf5c2b 100644 --- a/x-pack/plugins/apm/server/lib/helpers/service_metrics/index.ts +++ b/x-pack/plugins/apm/server/lib/helpers/service_metrics/index.ts @@ -8,23 +8,22 @@ import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { METRICSET_NAME } from '../../../../common/elasticsearch_fieldnames'; -import { APMConfig } from '../../..'; import { APMEventClient } from '../create_es_client/create_apm_event_client'; export async function getSearchAggregatedServiceMetrics({ - config, + serviceMetricsEnabled, start, end, apmEventClient, kuery, }: { - config: APMConfig; + serviceMetricsEnabled: boolean; start?: number; end?: number; apmEventClient: APMEventClient; kuery: string; }): Promise { - if (config.searchAggregatedServiceMetrics) { + if (serviceMetricsEnabled) { return getHasAggregatedServicesMetrics({ start, end, diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index 0c77c5b0be86f..6b73d72367d0f 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -7,6 +7,7 @@ import Boom from '@hapi/boom'; import { isoToEpochRt, jsonRt, toNumberRt } from '@kbn/io-ts-utils'; +import { enableServiceMetrics } from '@kbn/observability-plugin/common'; import * as t from 'io-ts'; import { uniq, mergeWith } from 'lodash'; import { @@ -122,6 +123,7 @@ const servicesRoute = createApmServerRoute({ probability, } = params.query; const savedObjectsClient = (await context.core).savedObjects.client; + const coreContext = await resources.context.core; const [setup, serviceGroup, randomSampler] = await Promise.all([ setupRequest(resources), @@ -132,8 +134,13 @@ const servicesRoute = createApmServerRoute({ ]); const { apmEventClient, config } = setup; + + const serviceMetricsEnabled = + await coreContext.uiSettings.client.get(enableServiceMetrics); + const { searchAggregatedTransactions, searchAggregatedServiceMetrics } = await getServiceInventorySearchSource({ + serviceMetricsEnabled, config, apmEventClient, kuery, @@ -208,6 +215,7 @@ const servicesDetailedStatisticsRoute = createApmServerRoute({ request, plugins: { security }, } = resources; + const coreContext = await resources.context.core; const { environment, kuery, offset, start, end, probability } = params.query; @@ -220,8 +228,13 @@ const servicesDetailedStatisticsRoute = createApmServerRoute({ ]); const { apmEventClient, config } = setup; + + const serviceMetricsEnabled = + await coreContext.uiSettings.client.get(enableServiceMetrics); + const { searchAggregatedTransactions, searchAggregatedServiceMetrics } = await getServiceInventorySearchSource({ + serviceMetricsEnabled, config, apmEventClient, kuery, diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index e4a36b379ff49..6fa68a617eead 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -25,6 +25,7 @@ export { apmOperationsTab, apmLabsButton, enableInfrastructureHostsView, + enableServiceMetrics, enableAwsLambdaMetrics, } from './ui_settings_keys'; diff --git a/x-pack/plugins/observability/common/ui_settings_keys.ts b/x-pack/plugins/observability/common/ui_settings_keys.ts index 8167c9a2c5ef5..f41e492d25050 100644 --- a/x-pack/plugins/observability/common/ui_settings_keys.ts +++ b/x-pack/plugins/observability/common/ui_settings_keys.ts @@ -21,3 +21,4 @@ export const apmOperationsTab = 'observability:apmOperationsTab'; export const apmLabsButton = 'observability:apmLabsButton'; export const enableInfrastructureHostsView = 'observability:enableInfrastructureHostsView'; export const enableAwsLambdaMetrics = 'observability:enableAwsLambdaMetrics'; +export const enableServiceMetrics = 'observability:apmEnableServiceMetrics'; diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 21296a9b3e35a..2d79e3b0e5e0a 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -23,6 +23,7 @@ import { apmOperationsTab, apmLabsButton, enableInfrastructureHostsView, + enableServiceMetrics, enableAwsLambdaMetrics, } from '../common/ui_settings_keys'; @@ -168,6 +169,21 @@ export const uiSettings: Record = { requiresPageReload: true, showInLabs: true, }, + [enableServiceMetrics]: { + category: [observabilityFeatureId], + name: i18n.translate('xpack.observability.apmEnableServiceMetrics', { + defaultMessage: 'Service metrics', + }), + value: false, + description: i18n.translate('xpack.observability.apmEnableServiceMetricsGroupsDescription', { + defaultMessage: + '{technicalPreviewLabel} Enables Service metrics. When is enabled, additional configuration in APM Server is required.', + values: { technicalPreviewLabel: `[${technicalPreviewLabel}]` }, + }), + schema: schema.boolean(), + requiresPageReload: true, + showInLabs: true, + }, [apmServiceInventoryOptimizedSorting]: { category: [observabilityFeatureId], name: i18n.translate('xpack.observability.apmServiceInventoryOptimizedSorting', { From f44f1d1dd8135964ed155ce806c1fda356a84dfd Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Wed, 21 Sep 2022 11:25:50 +0200 Subject: [PATCH 36/55] Fix removing a single field formatter (#141078) --- .../data_views/common/data_views/data_view.ts | 7 ++----- .../common/data_views/data_views.test.ts | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/plugins/data_views/common/data_views/data_view.ts b/src/plugins/data_views/common/data_views/data_view.ts index 42ab6d10834d4..f7f6451ca0453 100644 --- a/src/plugins/data_views/common/data_views/data_view.ts +++ b/src/plugins/data_views/common/data_views/data_view.ts @@ -15,7 +15,7 @@ import type { } from '@kbn/field-formats-plugin/common'; import { castEsToKbnFieldTypeName, ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types'; import { CharacterNotAllowedInField } from '@kbn/kibana-utils-plugin/common'; -import _, { cloneDeep, each, reject } from 'lodash'; +import { cloneDeep, each, reject } from 'lodash'; import type { DataViewAttributes, FieldAttrs, FieldAttrSet } from '..'; import type { DataViewField, IIndexPatternFieldList } from '../fields'; import { fieldList } from '../fields'; @@ -407,9 +407,6 @@ export class DataView implements DataViewBase { * Returns index pattern as saved object body for saving */ getAsSavedObjectBody(): DataViewAttributes { - const fieldFormatMap = _.isEmpty(this.fieldFormatMap) - ? undefined - : JSON.stringify(this.fieldFormatMap); const fieldAttrs = this.getFieldAttrs(); const runtimeFieldMap = this.runtimeFieldMap; @@ -419,7 +416,7 @@ export class DataView implements DataViewBase { timeFieldName: this.timeFieldName, sourceFilters: this.sourceFilters ? JSON.stringify(this.sourceFilters) : undefined, fields: JSON.stringify(this.fields?.filter((field) => field.scripted) ?? []), - fieldFormatMap, + fieldFormatMap: this.fieldFormatMap ? JSON.stringify(this.fieldFormatMap) : undefined, type: this.type!, typeMeta: JSON.stringify(this.typeMeta ?? {}), allowNoIndex: this.allowNoIndex ? this.allowNoIndex : undefined, diff --git a/src/plugins/data_views/common/data_views/data_views.test.ts b/src/plugins/data_views/common/data_views/data_views.test.ts index af95942393e11..a096cbe07cd53 100644 --- a/src/plugins/data_views/common/data_views/data_views.test.ts +++ b/src/plugins/data_views/common/data_views/data_views.test.ts @@ -350,6 +350,26 @@ describe('IndexPatterns', () => { expect(async () => await indexPatterns.get(id)).toBeDefined(); }); + test('can set and remove field format', async () => { + const id = 'id'; + setDocsourcePayload(id, savedObject); + const dataView = await indexPatterns.get(id); + dataView.setFieldFormat('field', { id: 'formatId' }); + await indexPatterns.updateSavedObject(dataView); + let lastCall = (savedObjectsClient.update as jest.Mock).mock.calls.pop() ?? []; + let [, , attrs] = lastCall; + expect(attrs).toHaveProperty('fieldFormatMap'); + expect(attrs.fieldFormatMap).toMatchInlineSnapshot(`"{\\"field\\":{\\"id\\":\\"formatId\\"}}"`); + dataView.deleteFieldFormat('field'); + await indexPatterns.updateSavedObject(dataView); + lastCall = (savedObjectsClient.update as jest.Mock).mock.calls.pop() ?? []; + [, , attrs] = lastCall; + + // https://github.com/elastic/kibana/issues/134873: must keep an empty object and not delete it + expect(attrs).toHaveProperty('fieldFormatMap'); + expect(attrs.fieldFormatMap).toMatchInlineSnapshot(`"{}"`); + }); + describe('getDefaultDataView', () => { beforeEach(() => { indexPatterns.clearCache(); From a160f0d2a97e26ce05a4e655d39cb620f8b2cded Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 21 Sep 2022 11:33:04 +0200 Subject: [PATCH 37/55] [Files] Added usage counters for delete, unshare and download (#140091) * added usage counters for download, unshare and delete * remove unused property * also count share usages * refactor how counters are formatted * added more specific error type counters * also record upload abort errors --- .../files/server/file_client/file_client.ts | 63 ++++++++++++++---- .../file_service/file_service_factory.ts | 13 +++- .../internal_file_share_service.ts | 64 ++++++++++++++----- x-pack/plugins/files/server/plugin.ts | 8 ++- .../files/server/routes/file_kind/upload.ts | 1 + x-pack/plugins/files/server/routes/types.ts | 2 + x-pack/plugins/files/server/usage/counters.ts | 31 +++++++++ x-pack/plugins/files/server/usage/index.ts | 2 + 8 files changed, 151 insertions(+), 33 deletions(-) create mode 100644 x-pack/plugins/files/server/usage/counters.ts diff --git a/x-pack/plugins/files/server/file_client/file_client.ts b/x-pack/plugins/files/server/file_client/file_client.ts index 595d0095a6625..ca806b6644f42 100644 --- a/x-pack/plugins/files/server/file_client/file_client.ts +++ b/x-pack/plugins/files/server/file_client/file_client.ts @@ -8,8 +8,9 @@ import moment from 'moment'; import { Readable } from 'stream'; import mimeType from 'mime'; import cuid from 'cuid'; -import type { Logger } from '@kbn/core/server'; +import { type Logger, SavedObjectsErrorHelpers } from '@kbn/core/server'; import type { AuditLogger } from '@kbn/security-plugin/server'; +import type { UsageCounter } from '@kbn/usage-collection-plugin/server'; import type { File, FileJSON, @@ -23,6 +24,7 @@ import type { BlobStorageClient, UploadOptions as BlobUploadOptions, } from '../blob_storage_service'; +import { getCounters, Counters } from '../usage'; import { File as FileImpl } from '../file'; import { FileShareServiceStart, InternalFileShareService } from '../file_share_service'; import { enforceMaxByteSizeTransform } from './stream_transforms'; @@ -59,6 +61,15 @@ export function createFileClient({ } export class FileClientImpl implements FileClient { + /** + * A usage counter instance that is shared across all FileClient instances. + */ + private static usageCounter: undefined | UsageCounter; + + public static configureUsageCounter(uc: UsageCounter) { + FileClientImpl.usageCounter = uc; + } + private readonly logAuditEvent: AuditLogger['log']; constructor( @@ -78,6 +89,14 @@ export class FileClientImpl implements FileClient { }; } + private getCounters() { + return getCounters(this.fileKind); + } + + private incrementUsageCounter(counter: Counters) { + FileClientImpl.usageCounter?.incrementCounter({ counterName: this.getCounters()[counter] }); + } + private instantiateFile(id: string, metadata: FileMetadata): File { return new FileImpl( id, @@ -144,19 +163,29 @@ export class FileClientImpl implements FileClient { } public async delete({ id, hasContent = true }: DeleteArgs) { - if (this.internalFileShareService) { - // Stop sharing this file - await this.internalFileShareService.deleteForFile({ id }); + this.incrementUsageCounter('DELETE'); + try { + if (this.internalFileShareService) { + // Stop sharing this file + await this.internalFileShareService.deleteForFile({ id }); + } + if (hasContent) await this.blobStorageClient.delete(id); + await this.metadataClient.delete({ id }); + this.logAuditEvent( + createAuditEvent({ + action: 'delete', + outcome: 'success', + message: `Deleted file with "${id}"`, + }) + ); + } catch (e) { + if (SavedObjectsErrorHelpers.isNotFoundError(e)) { + this.incrementUsageCounter('DELETE_ERROR_NOT_FOUND'); + } else { + this.incrementUsageCounter('DELETE_ERROR'); + } + throw e; } - if (hasContent) await this.blobStorageClient.delete(id); - await this.metadataClient.delete({ id }); - this.logAuditEvent( - createAuditEvent({ - action: 'delete', - outcome: 'success', - message: `Deleted file with "${id}"`, - }) - ); } public deleteContent: BlobStorageClient['delete'] = (arg) => { @@ -191,7 +220,13 @@ export class FileClientImpl implements FileClient { }; public download: BlobStorageClient['download'] = (args) => { - return this.blobStorageClient.download(args); + this.incrementUsageCounter('DOWNLOAD'); + try { + return this.blobStorageClient.download(args); + } catch (e) { + this.incrementUsageCounter('DOWNLOAD_ERROR'); + throw e; + } }; async share({ file, name, validUntil }: ShareArgs): Promise { diff --git a/x-pack/plugins/files/server/file_service/file_service_factory.ts b/x-pack/plugins/files/server/file_service/file_service_factory.ts index 7ced5d5e0100d..4c60145ba42af 100644 --- a/x-pack/plugins/files/server/file_service/file_service_factory.ts +++ b/x-pack/plugins/files/server/file_service/file_service_factory.ts @@ -13,9 +13,11 @@ import { } from '@kbn/core/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; -import type { File, FileJSON, FileMetadata } from '../../common'; +import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { File, FileJSON, FileMetadata } from '../../common'; import { fileObjectType, fileShareObjectType, hiddenTypes } from '../saved_objects'; import { BlobStorageService } from '../blob_storage_service'; +import { FileClientImpl } from '../file_client/file_client'; import { InternalFileShareService } from '../file_share_service'; import { CreateFileArgs, @@ -132,8 +134,15 @@ export class FileServiceFactoryImpl implements FileServiceFactory { /** * This function can only called during Kibana's setup phase */ - public static setup(savedObjectsSetup: SavedObjectsServiceSetup): void { + public static setup( + savedObjectsSetup: SavedObjectsServiceSetup, + usageCounter?: UsageCounter + ): void { savedObjectsSetup.registerType>(fileObjectType); savedObjectsSetup.registerType(fileShareObjectType); + if (usageCounter) { + FileClientImpl.configureUsageCounter(usageCounter); + InternalFileShareService.configureUsageCounter(usageCounter); + } } } diff --git a/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts b/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts index 6c9e09e5173b4..4d5bd95bf4b28 100644 --- a/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts +++ b/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts @@ -12,6 +12,7 @@ import { SavedObjectsErrorHelpers, } from '@kbn/core/server'; import { nodeBuilder, escapeKuery } from '@kbn/es-query'; +import { UsageCounter } from '@kbn/usage-collection-plugin/server'; import type { Pagination, FileShareJSON, @@ -22,6 +23,7 @@ import type { import { FILE_SO_TYPE } from '../../common/constants'; import type { File } from '../../common/types'; import { fileShareObjectType } from '../saved_objects'; +import { getCounters, Counters } from '../usage'; import { generateShareToken } from './generate_share_token'; import { FileShareServiceStart } from './types'; import { @@ -126,35 +128,67 @@ function validateCreateArgs({ validUntil }: CreateShareArgs): void { * @internal */ export class InternalFileShareService implements FileShareServiceStart { + private static usageCounter: undefined | UsageCounter; + + public static configureUsageCounter(uc: UsageCounter) { + InternalFileShareService.usageCounter = uc; + } + private readonly savedObjectsType = fileShareObjectType.name; constructor( private readonly savedObjects: SavedObjectsClientContract | ISavedObjectsRepository ) {} + private incrementUsageCounter(counter: Counters) { + InternalFileShareService.usageCounter?.incrementCounter({ + counterName: getCounters('share_service')[counter], + }); + } + public async share(args: CreateShareArgs): Promise { - validateCreateArgs(args); - const { file, name, validUntil } = args; - const so = await this.savedObjects.create( - this.savedObjectsType, - { - created: new Date().toISOString(), - name, - valid_until: validUntil ? validUntil : Number(moment().add(30, 'days')), - token: generateShareToken(), - }, - { - references: [{ name: file.data.name, id: file.data.id, type: FILE_SO_TYPE }], - } - ); + this.incrementUsageCounter('SHARE'); + try { + validateCreateArgs(args); + const { file, name, validUntil } = args; + const so = await this.savedObjects.create( + this.savedObjectsType, + { + created: new Date().toISOString(), + name, + valid_until: validUntil ? validUntil : Number(moment().add(30, 'days')), + token: generateShareToken(), + }, + { + references: [{ name: file.data.name, id: file.data.id, type: FILE_SO_TYPE }], + } + ); - return { ...toFileShareJSON(so), token: so.attributes.token }; + return { ...toFileShareJSON(so), token: so.attributes.token }; + } catch (e) { + if (e instanceof ExpiryDateInThePastError) { + this.incrementUsageCounter('SHARE_ERROR_EXPIRATION_IN_PAST'); + } else if (SavedObjectsErrorHelpers.isForbiddenError(e)) { + this.incrementUsageCounter('SHARE_ERROR_FORBIDDEN'); + } else if (SavedObjectsErrorHelpers.isConflictError(e)) { + this.incrementUsageCounter('SHARE_ERROR_CONFLICT'); + } else { + this.incrementUsageCounter('SHARE_ERROR'); + } + throw e; + } } public async delete({ id }: DeleteArgs): Promise { + this.incrementUsageCounter('UNSHARE'); try { await this.savedObjects.delete(this.savedObjectsType, id); } catch (e) { + if (SavedObjectsErrorHelpers.isNotFoundError(e)) { + this.incrementUsageCounter('UNSHARE_ERROR_NOT_FOUND'); + } else { + this.incrementUsageCounter('UNSHARE_ERROR'); + } if (SavedObjectsErrorHelpers.isNotFoundError(e)) { throw new FileShareNotFoundError(`File share with id "${id}" not found.`); } diff --git a/x-pack/plugins/files/server/plugin.ts b/x-pack/plugins/files/server/plugin.ts index 3fa031a71141c..ebac15c8f7a0f 100755 --- a/x-pack/plugins/files/server/plugin.ts +++ b/x-pack/plugins/files/server/plugin.ts @@ -25,7 +25,7 @@ import { } from './file_kinds_registry'; import type { FilesRequestHandlerContext, FilesRouter } from './routes/types'; import { registerRoutes } from './routes'; -import { registerUsageCollector } from './usage'; +import { Counters, registerUsageCollector } from './usage'; export class FilesPlugin implements Plugin { private readonly logger: Logger; @@ -40,7 +40,8 @@ export class FilesPlugin implements Plugin( @@ -51,6 +52,9 @@ export class FilesPlugin implements Plugin this.fileServiceFactory!.asScoped(req), asInternalUser: () => this.fileServiceFactory!.asInternal(), logger: this.logger.get('files-routes'), + usageCounter: usageCounter + ? (counter: Counters) => usageCounter.incrementCounter({ counterName: counter }) + : undefined, }, }; } diff --git a/x-pack/plugins/files/server/routes/file_kind/upload.ts b/x-pack/plugins/files/server/routes/file_kind/upload.ts index f82eb5565af3b..90f09d1c15a0b 100644 --- a/x-pack/plugins/files/server/routes/file_kind/upload.ts +++ b/x-pack/plugins/files/server/routes/file_kind/upload.ts @@ -55,6 +55,7 @@ export const handler: FileKindsRequestHandler = async ( ) { return res.badRequest({ body: { message: e.message } }); } else if (e instanceof fileErrors.AbortedUploadError) { + fileService.usageCounter?.('UPLOAD_ERROR_ABORT'); fileService.logger.error(e); return res.customError({ body: { message: e.message }, statusCode: 499 }); } diff --git a/x-pack/plugins/files/server/routes/types.ts b/x-pack/plugins/files/server/routes/types.ts index eccc55e769e58..357ad0984244c 100644 --- a/x-pack/plugins/files/server/routes/types.ts +++ b/x-pack/plugins/files/server/routes/types.ts @@ -15,6 +15,7 @@ import type { Logger, } from '@kbn/core/server'; import type { FileServiceStart } from '../file_service'; +import { Counters } from '../usage'; export interface FilesRequestHandlerContext extends RequestHandlerContext { files: Promise<{ @@ -22,6 +23,7 @@ export interface FilesRequestHandlerContext extends RequestHandlerContext { asCurrentUser: () => FileServiceStart; asInternalUser: () => FileServiceStart; logger: Logger; + usageCounter?: (counter: Counters) => void; }; }>; } diff --git a/x-pack/plugins/files/server/usage/counters.ts b/x-pack/plugins/files/server/usage/counters.ts new file mode 100644 index 0000000000000..65287fe1cea26 --- /dev/null +++ b/x-pack/plugins/files/server/usage/counters.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export function getCounters(fileKind: string) { + return { + DELETE: `delete:${fileKind}`, + DELETE_ERROR: `delete:error:unknown:${fileKind}`, + DELETE_ERROR_NOT_FOUND: `delete:error:not_found:${fileKind}`, + + SHARE: `share:${fileKind}`, + SHARE_ERROR: `share:error:unknown:${fileKind}`, + SHARE_ERROR_EXPIRATION_IN_PAST: `share:error:expiration_in_past:${fileKind}`, + SHARE_ERROR_FORBIDDEN: `share:error:forbidden:${fileKind}`, + SHARE_ERROR_CONFLICT: `share:error:conflict:${fileKind}`, + + UNSHARE: `unshare:${fileKind}`, + UNSHARE_ERROR: `unshare:error:unknown:${fileKind}`, + UNSHARE_ERROR_NOT_FOUND: `unshare:error:not_found:${fileKind}`, + + DOWNLOAD: `download:${fileKind}`, + DOWNLOAD_ERROR: `download:error:unknown:${fileKind}`, + + UPLOAD_ERROR_ABORT: `upload:error:abort:${fileKind}`, + }; +} + +export type Counters = keyof ReturnType; diff --git a/x-pack/plugins/files/server/usage/index.ts b/x-pack/plugins/files/server/usage/index.ts index 59f577ba20b70..af624244bcdd5 100644 --- a/x-pack/plugins/files/server/usage/index.ts +++ b/x-pack/plugins/files/server/usage/index.ts @@ -6,3 +6,5 @@ */ export { registerUsageCollector } from './register_usage_collector'; +export type { Counters } from './counters'; +export { getCounters } from './counters'; From f64c9c94f7db04ecf07dd95766dbed718a9710df Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Wed, 21 Sep 2022 12:20:43 +0200 Subject: [PATCH 38/55] [SearchBar] Allow show refresh button as an icon (#141088) --- .../public/__stories__/search_bar.stories.tsx | 42 +++++++++++++++++++ .../query_bar_top_row.test.tsx | 17 ++++++++ .../query_string_input/query_bar_top_row.tsx | 23 +++++++--- .../public/search_bar/create_search_bar.tsx | 2 + .../public/search_bar/search_bar.tsx | 4 +- 5 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/plugins/unified_search/public/__stories__/search_bar.stories.tsx b/src/plugins/unified_search/public/__stories__/search_bar.stories.tsx index 30b4d993e6954..40d3abfb7fae0 100644 --- a/src/plugins/unified_search/public/__stories__/search_bar.stories.tsx +++ b/src/plugins/unified_search/public/__stories__/search_bar.stories.tsx @@ -566,4 +566,46 @@ storiesOf('SearchBar', module) }, isDisabled: true, } as SearchBarProps) + ) + .add('no submit button', () => + wrapSearchBarInContext({ + dataViewPickerComponentProps: { + currentDataViewId: '1234', + trigger: { + 'data-test-subj': 'dataView-switch-link', + label: 'logstash-*', + title: 'logstash-*', + }, + onChangeDataView: action('onChangeDataView'), + }, + showSubmitButton: false, + } as SearchBarProps) + ) + .add('submit button always as icon', () => + wrapSearchBarInContext({ + dataViewPickerComponentProps: { + currentDataViewId: '1234', + trigger: { + 'data-test-subj': 'dataView-switch-link', + label: 'logstash-*', + title: 'logstash-*', + }, + onChangeDataView: action('onChangeDataView'), + }, + submitButtonStyle: 'iconOnly', + } as SearchBarProps) + ) + .add('submit button always as a full button', () => + wrapSearchBarInContext({ + dataViewPickerComponentProps: { + currentDataViewId: '1234', + trigger: { + 'data-test-subj': 'dataView-switch-link', + label: 'logstash-*', + title: 'logstash-*', + }, + onChangeDataView: action('onChangeDataView'), + }, + submitButtonStyle: 'full', + } as SearchBarProps) ); diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx index 052e0ab7b32c8..7be320d5d7aeb 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.test.tsx @@ -208,6 +208,23 @@ describe('QueryBarTopRowTopRow', () => { expect(component.find(TIMEPICKER_SELECTOR).length).toBe(1); }); + it('Should render update button as icon button', () => { + const component = mount( + wrapQueryBarTopRowInContext({ + isDirty: false, + screenTitle: 'Another Screen', + showDatePicker: true, + showSubmitButton: true, + submitButtonStyle: 'iconOnly', + dateRangeFrom: 'now-7d', + dateRangeTo: 'now', + timeHistory: mockTimeHistory, + }) + ); + + expect(component.find(REFRESH_BUTTON_SELECTOR).prop('iconOnly')).toBe(true); + }); + it('Should render the timefilter duration container for sharing', () => { const component = mount( wrapQueryBarTopRowInContext({ diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index c0848f630daa8..ca4a06d6a86f8 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -15,6 +15,7 @@ import type { Filter, TimeRange, Query, AggregateQuery } from '@kbn/es-query'; import { getAggregateQueryMode, isOfQueryType, isOfAggregateQueryType } from '@kbn/es-query'; import { EMPTY } from 'rxjs'; import { map } from 'rxjs/operators'; +import { throttle } from 'lodash'; import { EuiFlexGroup, EuiFlexItem, @@ -93,6 +94,13 @@ export interface QueryBarTopRowProps filterBar?: React.ReactNode; showDatePickerAsBadge?: boolean; showSubmitButton?: boolean; + /** + * Style of the submit button + * `iconOnly` - use IconButton + * `full` - use SuperUpdateButton + * (default) `auto` - `iconOnly` on smaller screens, and `full` on larger screens + */ + submitButtonStyle?: 'auto' | 'iconOnly' | 'full'; suggestionsSize?: SuggestionsListSize; isScreenshotMode?: boolean; onTextLangQuerySubmit: (query?: Query | AggregateQuery) => void; @@ -142,18 +150,23 @@ export const QueryBarTopRow = React.memo( const isMobile = useIsWithinBreakpoints(['xs', 's']); const [isXXLarge, setIsXXLarge] = useState(false); const [codeEditorIsExpanded, setCodeEditorIsExpanded] = useState(false); + const submitButtonStyle: QueryBarTopRowProps['submitButtonStyle'] = + props.submitButtonStyle ?? 'auto'; + const submitButtonIconOnly = + submitButtonStyle === 'auto' ? !isXXLarge : submitButtonStyle === 'iconOnly'; useEffect(() => { - function handleResize() { + if (submitButtonStyle !== 'auto') return; + + const handleResize = throttle(() => { setIsXXLarge(window.innerWidth >= 1440); - } + }, 50); - window.removeEventListener('resize', handleResize); window.addEventListener('resize', handleResize); handleResize(); return () => window.removeEventListener('resize', handleResize); - }, []); + }, [submitButtonStyle]); const { showQueryInput = true, @@ -404,7 +417,7 @@ export const QueryBarTopRow = React.memo( { textBasedLanguageModeErrors?: Error[]; onTextBasedSavedAndExit?: ({ onSave }: OnSaveTextLanguageQueryProps) => void; showSubmitButton?: boolean; + submitButtonStyle?: QueryBarTopRowProps['submitButtonStyle']; // defines size of suggestions query popover suggestionsSize?: SuggestionsListSize; isScreenshotMode?: boolean; @@ -544,6 +545,7 @@ class SearchBarUI extends C this.props.customSubmitButton ? this.props.customSubmitButton : undefined } showSubmitButton={this.props.showSubmitButton} + submitButtonStyle={this.props.submitButtonStyle} dataTestSubj={this.props.dataTestSubj} indicateNoData={this.props.indicateNoData} placeholder={this.props.placeholder} From dd7c1ecfed6d042d5208a6f6244cbd804f3d13d2 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 21 Sep 2022 12:21:40 +0200 Subject: [PATCH 39/55] [Actionable Observability] Fix alert summary widget bug in non-default space (#140842) * Remove sending index for fetching data * Fix test * Revert "Remove sending index for fetching data" This reverts commit 29caa5ab09a4abfc2ef846c9fc253add6d438fb2. * Revert "Fix test" This reverts commit e2b03b1ac52301e851f681e362c2b8cbae0c7b9c. * Change getting alert index based on spacename logic * Fix APM Alert test * Rename DEFAULT_SPACE to INDEX_ALIAS * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../rule_registry/server/alert_data_client/alerts_client.ts | 5 ++++- .../security_and_spaces/tests/basic/get_alerts_index.ts | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts index 3727675d99852..b6332bcd47aa4 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts @@ -10,6 +10,7 @@ import { PublicMethodsOf } from '@kbn/utility-types'; import { Filter, buildEsQuery, EsQueryConfig } from '@kbn/es-query'; import { decodeVersion, encodeHitVersion } from '@kbn/securitysolution-es-utils'; import { + AlertConsumers, getEsQueryConfig, getSafeSortIds, isValidFeatureId, @@ -674,7 +675,9 @@ export class AlertsClient { if (index == null) { throw new Error(`This feature id ${feature} should be associated to an alert index`); } - return index?.getPrimaryAlias(this.spaceId ?? '*') ?? ''; + return ( + index?.getPrimaryAlias(feature === AlertConsumers.SIEM ? this.spaceId ?? '*' : '*') ?? '' + ); }); return toReturn; diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts index 3b30f1b64dc2b..3d333d91da153 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alerts_index.ts @@ -20,6 +20,7 @@ export default ({ getService }: FtrProviderContext) => { const TEST_URL = '/internal/rac/alerts'; const ALERTS_INDEX_URL = `${TEST_URL}/index`; const SPACE1 = 'space1'; + const INDEX_ALIAS = '*'; const APM_ALERT_INDEX = '.alerts-observability.apm.alerts'; const SECURITY_SOLUTION_ALERT_INDEX = '.alerts-security.alerts'; @@ -53,12 +54,12 @@ export default ({ getService }: FtrProviderContext) => { describe('Users:', () => { it(`${obsOnlySpacesAll.username} should be able to access the APM alert in ${SPACE1}`, async () => { const indexNames = await getAPMIndexName(obsOnlySpacesAll, SPACE1); - expect(indexNames.includes(`${APM_ALERT_INDEX}-${SPACE1}`)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below + expect(indexNames.includes(`${APM_ALERT_INDEX}-${INDEX_ALIAS}`)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below }); it(`${superUser.username} should be able to access the APM alert in ${SPACE1}`, async () => { const indexNames = await getAPMIndexName(superUser, SPACE1); - expect(indexNames.includes(`${APM_ALERT_INDEX}-${SPACE1}`)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below + expect(indexNames.includes(`${APM_ALERT_INDEX}-${INDEX_ALIAS}`)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below }); it(`${secOnlyRead.username} should NOT be able to access the APM alert in ${SPACE1}`, async () => { From 0d8de4df69f8084a94cdd9638d7de510813cb5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Alvarez=20Pi=C3=B1eiro?= <95703246+emilioalvap@users.noreply.github.com> Date: Wed, 21 Sep 2022 12:23:04 +0200 Subject: [PATCH 40/55] [Synthetics UI] Add playwright options to synthetics ui monitor form (#140044) * Add playwright options to synthetics ui monitor form * Docs link to synthetics command reference * Update packages/kbn-doc-links/src/get_doc_links.ts Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-doc-links/src/get_doc_links.ts | 1 + packages/kbn-doc-links/src/types.ts | 1 + .../monitor_add_edit/fields/code_editor.tsx | 4 ++ .../monitor_add_edit/form/field_config.tsx | 54 +++++++++++++++++++ .../monitor_add_edit/form/form_config.tsx | 17 ++++++ .../monitor_add_edit/form/validation.tsx | 17 ++++++ .../synthetics/public/kibana_services.ts | 15 ++++++ x-pack/plugins/synthetics/public/plugin.ts | 2 + 8 files changed, 111 insertions(+) create mode 100644 x-pack/plugins/synthetics/public/kibana_services.ts diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index 413e8905bea93..8c39a15033ce1 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -447,6 +447,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { monitorUptimeSynthetics: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/monitor-uptime-synthetics.html`, userExperience: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/user-experience.html`, createAlerts: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/create-alerts.html`, + syntheticsCommandReference: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetics-configuration.html#synthetics-configuration-playwright-options`, }, alerting: { guide: `${KIBANA_DOCS}create-and-manage-rules.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index 1ee0d5414b275..3735c1abbddbf 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -331,6 +331,7 @@ export interface DocLinks { monitorUptimeSynthetics: string; userExperience: string; createAlerts: string; + syntheticsCommandReference: string; }>; readonly alerting: Record; readonly maps: Readonly<{ diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/code_editor.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/code_editor.tsx index 6d7fa2cbc441f..e5d8c8152d68f 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/code_editor.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/code_editor.tsx @@ -58,3 +58,7 @@ const MonacoCodeContainer = euiStyled.div` z-index: 0; } `; + +export const JSONEditor = (props: any) => { + return ; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx index 83ba909f3063c..644901aadd5c2 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/field_config.tsx @@ -29,6 +29,7 @@ import { EuiLink, EuiTextArea, } from '@elastic/eui'; +import { getDocLinks } from '../../../../../kibana_services'; import { useMonitorName } from '../hooks/use_monitor_name'; import { MonitorTypeRadioGroup } from '../fields/monitor_type_radio_group'; import { @@ -53,6 +54,7 @@ import { ComboBox } from '../fields/combo_box'; import { SourceField } from '../fields/source_field'; import { getDefaultFormFields } from './defaults'; import { validate, validateHeaders, WHOLE_NUMBERS_ONLY, FLOATS_ONLY } from './validation'; +import { JSONEditor } from '../fields/code_editor'; const getScheduleContent = (value: number) => { if (value > 60) { @@ -1006,4 +1008,56 @@ export const FIELD: Record = { required: true, }), }, + [ConfigKey.PLAYWRIGHT_OPTIONS]: { + fieldKey: ConfigKey.PLAYWRIGHT_OPTIONS, + component: JSONEditor, + label: i18n.translate('xpack.synthetics.monitorConfig.playwrightOptions.label', { + defaultMessage: 'Playwright options', + }), + helpText: ( + + {i18n.translate('xpack.synthetics.monitorConfig.playwrightOptions.helpText', { + defaultMessage: 'Configure Playwright agent with custom options. ', + })} + + {i18n.translate('xpack.synthetics.monitorConfig.playwrightOptions.learnMore', { + defaultMessage: 'Learn more', + })} + + + ), + error: i18n.translate('xpack.synthetics.monitorConfig.playwrightOptions.error', { + defaultMessage: 'Invalid JSON format', + }), + ariaLabel: i18n.translate( + 'xpack.synthetics.monitorConfig.playwrightOptions.codeEditor.json.ariaLabel', + { + defaultMessage: 'Playwright options JSON code editor', + } + ), + controlled: true, + required: false, + props: ({ + field, + setValue, + }: { + field?: ControllerRenderProps; + setValue: UseFormReturn['setValue']; + }) => ({ + onChange: (json: string) => setValue(ConfigKey.PLAYWRIGHT_OPTIONS, json), + }), + validation: () => ({ + validate: (value) => { + const validateFn = validate[DataStream.BROWSER][ConfigKey.PLAYWRIGHT_OPTIONS]; + if (validateFn) { + return !validateFn({ + [ConfigKey.PLAYWRIGHT_OPTIONS]: value, + }); + } + }, + }), + }, }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx index 9f11f2c53c06e..132e3ab0343e1 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/form_config.tsx @@ -103,6 +103,21 @@ export const TCP_ADVANCED = { }, }; +export const BROWSER_ADVANCED = [ + { + title: i18n.translate('xpack.synthetics.monitorConfig.section.syntAgentOptions.title', { + defaultMessage: 'Synthetics agent options', + }), + description: i18n.translate( + 'xpack.synthetics.monitorConfig.section.syntAgentOptions.description', + { + defaultMessage: 'Provide fine-tuned configuration for the synthetics agent.', + } + ), + components: [FIELD[`${ConfigKey.PLAYWRIGHT_OPTIONS}`]], + }, +]; + interface AdvancedFieldGroup { title: string; description: string; @@ -197,6 +212,7 @@ export const FORM_CONFIG: FieldConfig = { FIELD[ConfigKey.NAMESPACE], ], }, + ...BROWSER_ADVANCED, ], }, [FormMonitorType.SINGLE]: { @@ -220,6 +236,7 @@ export const FORM_CONFIG: FieldConfig = { FIELD[ConfigKey.NAMESPACE], ], }, + ...BROWSER_ADVANCED, ], }, [FormMonitorType.ICMP]: { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.tsx index de3ce4bc327fd..00330134344c4 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/form/validation.tsx @@ -57,6 +57,21 @@ export const validateTimeout = ({ return parseFloat(timeout) > schedule; }; +export const validJSONFormat = (value: string) => { + let obj; + + try { + obj = JSON.parse(value); + if (!obj || typeof obj !== 'object') { + return false; + } + } catch (e) { + return false; + } + + return true; +}; + // validation functions return true when invalid const validateCommon: ValidationLibrary = { [ConfigKey.SCHEDULE]: ({ [ConfigKey.SCHEDULE]: value }) => { @@ -145,6 +160,8 @@ const validateBrowser: ValidationLibrary = { [ConfigKey.UPLOAD_SPEED]: ({ [ConfigKey.UPLOAD_SPEED]: uploadSpeed }) => validateThrottleValue(uploadSpeed), [ConfigKey.LATENCY]: ({ [ConfigKey.LATENCY]: latency }) => validateThrottleValue(latency, true), + [ConfigKey.PLAYWRIGHT_OPTIONS]: ({ [ConfigKey.PLAYWRIGHT_OPTIONS]: playwrightOptions }) => + playwrightOptions ? !validJSONFormat(playwrightOptions) : false, }; export type ValidateDictionary = Record; diff --git a/x-pack/plugins/synthetics/public/kibana_services.ts b/x-pack/plugins/synthetics/public/kibana_services.ts new file mode 100644 index 0000000000000..eb413b0260fb1 --- /dev/null +++ b/x-pack/plugins/synthetics/public/kibana_services.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoreStart } from '@kbn/core/public'; + +let coreStart: CoreStart; +export function setStartServices(core: CoreStart) { + coreStart = core; +} + +export const getDocLinks = () => coreStart.docLinks; diff --git a/x-pack/plugins/synthetics/public/plugin.ts b/x-pack/plugins/synthetics/public/plugin.ts index 8557f954e713b..00af06f7570e2 100644 --- a/x-pack/plugins/synthetics/public/plugin.ts +++ b/x-pack/plugins/synthetics/public/plugin.ts @@ -55,6 +55,7 @@ import { } from './legacy_uptime/lib/alert_types'; import { monitorDetailNavigatorParams } from './apps/locators/monitor_detail'; import { editMonitorNavigatorParams } from './apps/locators/edit_monitor'; +import { setStartServices } from './kibana_services'; export interface ClientPluginsSetup { home?: HomePublicPluginSetup; @@ -228,6 +229,7 @@ export class UptimePlugin public start(start: CoreStart, plugins: ClientPluginsStart): void { if (plugins.fleet) { const { registerExtension } = plugins.fleet; + setStartServices(start); registerExtension({ package: 'synthetics', From 64e58d2afc52b90bb4d4699a3bb50a66bae3e34d Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 21 Sep 2022 12:28:50 +0100 Subject: [PATCH 41/55] [Fleet] Handle verification errors from get package info endpoint (#140756) * add ignoreUnverified param to get info route * show confirm modal when atempting to view unverified pkg * add pkg verification tests * remove .only * fix tests * remove unused test pkg * fix API docs * restrict import * remove unused params * fix tests * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * remove commented tests * add missing mock * fix more tests * bundle size * fix unit tests Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/fleet/common/openapi/bundled.json | 9 +++ .../plugins/fleet/common/openapi/bundled.yaml | 6 ++ ...epm@packages@{pkg_name}@{pkg_version}.yaml | 5 ++ .../agents/agent_list_page/index.test.tsx | 5 ++ .../confirm_open_unverified_modal.tsx | 76 ++++++++++++++++++ .../applications/integrations/hooks/index.ts | 1 + .../hooks/use_confirm_force_install.tsx | 8 +- .../hooks/use_confirm_open_unverified.tsx | 53 ++++++++++++ .../agent_enrollment_flyout.test.mocks.ts | 12 ++- .../fleet/public/hooks/use_request/epm.ts | 40 ++++++++- .../fleet/server/routes/epm/handlers.ts | 5 +- .../server/routes/package_policy/handlers.ts | 1 + .../fleet/server/services/epm/packages/get.ts | 10 ++- .../fleet/server/types/rest_spec/epm.ts | 3 + .../fleet_api_integration/apis/epm/get.ts | 13 +++ .../agent/input/input.yml.hbs | 18 +++++ .../src/input_only-0.1.0/changelog.yml | 6 ++ .../src/input_only-0.1.0/docs/README.md | 1 + .../src/input_only-0.1.0/fields/input.yml | 4 + .../src/input_only-0.1.0/img/sample-logo.svg | 1 + .../img/sample-screenshot.png | Bin 0 -> 18849 bytes .../src/input_only-0.1.0/manifest.yml | 45 +++++++++++ .../zips/input_only_unverified-0.1.0.zip | Bin 0 -> 30629 bytes .../zips/input_only_unverified-0.1.0.zip.sig | 16 ++++ 24 files changed, 326 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/integrations/components/confirm_open_unverified_modal.tsx create mode 100644 x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_open_unverified.tsx create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/agent/input/input.yml.hbs create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/changelog.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/docs/README.md create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/fields/input.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/img/sample-logo.svg create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/img/sample-screenshot.png create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/manifest.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/zips/input_only_unverified-0.1.0.zip create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/zips/input_only_unverified-0.1.0.zip.sig diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index 138279d7b7f5a..b7bbc22d5f1eb 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -606,8 +606,17 @@ "name": "pkgVersion", "in": "path", "required": true + }, + { + "schema": { + "type": "boolean" + }, + "name": "ignoreUnverified", + "description": "Ignore if the package is fails signature verification", + "in": "query" } ], + "required": true, "post": { "summary": "Packages - Install", "tags": [], diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 60c305097c4cc..fab23c6596a8f 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -376,6 +376,12 @@ paths: name: pkgVersion in: path required: true + - schema: + type: boolean + name: ignoreUnverified + description: Ignore if the package is fails signature verification + in: query + required: true post: summary: Packages - Install tags: [] diff --git a/x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml b/x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml index 8164d04fc98f1..b0ef55cb7e52d 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/epm@packages@{pkg_name}@{pkg_version}.yaml @@ -47,6 +47,11 @@ parameters: name: pkgVersion in: path required: true + - schema: + type: boolean + name: ignoreUnverified + description: 'Ignore if the package is fails signature verification' + in: query post: summary: Packages - Install tags: [] diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx index 74a418bebde77..98b1688308203 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx @@ -21,6 +21,11 @@ jest.mock('../../../../integrations/hooks/use_confirm_force_install', () => ({ })); jest.mock('../../../hooks', () => ({ ...jest.requireActual('../../../hooks'), + UIExtensionsContext: { + Provider: (props: any) => { + return props.children; + }, + }, sendGetAgents: jest.fn(), useGetAgentPolicies: jest.fn().mockReturnValue({ data: { items: [{ id: 'policy1' }] }, diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/confirm_open_unverified_modal.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/confirm_open_unverified_modal.tsx new file mode 100644 index 0000000000000..a11556d81aec4 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/components/confirm_open_unverified_modal.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiConfirmModal, EuiCallOut, EuiLink } from '@elastic/eui'; +import type { DocLinksStart } from '@kbn/core/public'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import React from 'react'; + +export const ConfirmOpenUnverifiedModal: React.FC<{ + onCancel: () => void; + onConfirm: () => void; + pkgName: string; + docLinks: DocLinksStart; +}> = ({ onCancel, onConfirm, pkgName, docLinks }) => { + return ( + + + + } + onCancel={onCancel} + onConfirm={onConfirm} + cancelButtonText={ + + } + confirmButtonText={ + + } + buttonColor="danger" + data-test-subj="ConfirmOpenUnverifiedModal" + > + + + + ), + }} + /> + } + /> + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/index.ts b/x-pack/plugins/fleet/public/applications/integrations/hooks/index.ts index 19fe6c0467b22..5b6b19af169f0 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/hooks/index.ts +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/index.ts @@ -13,3 +13,4 @@ export * from './use_package_install'; export * from './use_agent_policy_context'; export * from './use_integrations_state'; export * from './use_confirm_force_install'; +export * from './use_confirm_open_unverified'; diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_force_install.tsx b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_force_install.tsx index 94c6e7ddd5541..1adacb5fe733d 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_force_install.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_force_install.tsx @@ -8,7 +8,7 @@ import type { DocLinksStart, OverlayStart } from '@kbn/core/public'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; -import React from 'react'; +import React, { useCallback } from 'react'; import { useStartServices } from '../../fleet/hooks'; import { ConfirmForceInstallModal } from '../components'; @@ -44,6 +44,8 @@ const confirmForceInstall = ({ export const useConfirmForceInstall = () => { const { overlays, docLinks } = useStartServices(); - return (pkg: { name: string; version: string }) => - confirmForceInstall({ pkg, overlays, docLinks }); + return useCallback( + (pkg: { name: string; version: string }) => confirmForceInstall({ pkg, overlays, docLinks }), + [docLinks, overlays] + ); }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_open_unverified.tsx b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_open_unverified.tsx new file mode 100644 index 0000000000000..1d36a13d319a8 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/integrations/hooks/use_confirm_open_unverified.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DocLinksStart, OverlayStart } from '@kbn/core/public'; +import { toMountPoint } from '@kbn/kibana-react-plugin/public'; + +import React, { useCallback } from 'react'; + +// Direct imports are important here, importing all hooks breaks unit tests +// and increases bundle size because this is imported on first page load +import { useStartServices } from '../../../hooks/use_core'; +import { ConfirmOpenUnverifiedModal } from '../components/confirm_open_unverified_modal'; + +const confirmOpenUnverified = ({ + pkgName, + overlays, + docLinks, +}: { + pkgName: string; + overlays: OverlayStart; + docLinks: DocLinksStart; +}): Promise => + new Promise((resolve) => { + const session = overlays.openModal( + toMountPoint( + { + session.close(); + resolve(true); + }} + onCancel={() => { + session.close(); + resolve(false); + }} + docLinks={docLinks} + /> + ) + ); + }); + +export const useConfirmOpenUnverified = () => { + const { overlays, docLinks } = useStartServices(); + + return useCallback( + (pkgName: string) => confirmOpenUnverified({ pkgName, overlays, docLinks }), + [docLinks, overlays] + ); +}; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts index 22458b998d3ed..371edf0c6f6e9 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/agent_enrollment_flyout.test.mocks.ts @@ -17,9 +17,15 @@ jest.mock('../../hooks/use_request', () => { const module = jest.requireActual('../../hooks/use_request'); return { ...module, - useGetSettings: jest.fn(), - sendGetOneAgentPolicy: jest.fn(), - useGetAgents: jest.fn(), + useGetSettings: jest.fn().mockReturnValue({ + data: { item: { fleet_server_hosts: ['test'] } }, + }), + sendGetOneAgentPolicy: jest.fn().mockResolvedValue({ + data: { item: { package_policies: [] } }, + }), + useGetAgents: jest.fn().mockReturnValue({ + data: { items: [{ policy_id: 'fleet-server-policy' }] }, + }), useGetAgentPolicies: jest.fn(), }; }); diff --git a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts index 3448542bf7df1..57b2b93fabb25 100644 --- a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts +++ b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts @@ -7,7 +7,9 @@ import useAsync from 'react-use/lib/useAsync'; -import { epmRouteService } from '../../services'; +import { useEffect, useState } from 'react'; + +import { epmRouteService, isVerificationError } from '../../services'; import type { GetCategoriesRequest, GetCategoriesResponse, @@ -24,6 +26,8 @@ import type { FleetErrorResponse, GetStatsResponse } from '../../../common/types import { getCustomIntegrations } from '../../services/custom_integrations'; +import { useConfirmOpenUnverified } from '../../applications/integrations/hooks/use_confirm_open_unverified'; + import { useRequest, sendRequest } from './use_request'; export function useGetAppendCustomIntegrations() { @@ -67,11 +71,34 @@ export const useGetLimitedPackages = () => { }); }; -export const useGetPackageInfoByKey = (pkgName: string, pkgVersion?: string) => { - return useRequest({ +export const useGetPackageInfoByKey = ( + pkgName: string, + pkgVersion?: string, + ignoreUnverified: boolean = false +) => { + const confirmOpenUnverified = useConfirmOpenUnverified(); + const [ignoreUnverifiedQueryParam, setIgnoreUnverifiedQueryParam] = useState(ignoreUnverified); + const res = useRequest({ path: epmRouteService.getInfoPath(pkgName, pkgVersion), method: 'get', + query: ignoreUnverifiedQueryParam ? { ignoreUnverified: ignoreUnverifiedQueryParam } : {}, }); + + useEffect(() => { + const confirm = async () => { + const forceInstall = await confirmOpenUnverified(pkgName); + + if (forceInstall) { + setIgnoreUnverifiedQueryParam(true); + } + }; + + if (res.error && isVerificationError(res.error)) { + confirm(); + } + }, [res.error, pkgName, pkgVersion, confirmOpenUnverified]); + + return res; }; export const useGetPackageStats = (pkgName: string) => { @@ -81,10 +108,15 @@ export const useGetPackageStats = (pkgName: string) => { }); }; -export const sendGetPackageInfoByKey = (pkgName: string, pkgVersion?: string) => { +export const sendGetPackageInfoByKey = ( + pkgName: string, + pkgVersion?: string, + ignoreUnverified?: boolean +) => { return sendRequest({ path: epmRouteService.getInfoPath(pkgName, pkgVersion), method: 'get', + query: ignoreUnverified ? { ignoreUnverified } : {}, }); }; diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts index e5e2cc5128074..242e272cd184b 100644 --- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts @@ -194,11 +194,13 @@ export const getFileHandler: FleetRequestHandler< }; export const getInfoHandler: FleetRequestHandler< - TypeOf + TypeOf, + TypeOf > = async (context, request, response) => { try { const savedObjectsClient = (await context.fleet).epm.internalSoClient; const { pkgName, pkgVersion } = request.params; + const { ignoreUnverified = false } = request.query; if (pkgVersion && !semverValid(pkgVersion)) { throw new FleetError('Package version is not a valid semver'); } @@ -207,6 +209,7 @@ export const getInfoHandler: FleetRequestHandler< pkgName, pkgVersion: pkgVersion || '', skipArchive: true, + ignoreUnverified, }); const body: GetInfoResponse = { item: res, diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts index 2b4ebbb5728f2..765c6c649db25 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts @@ -203,6 +203,7 @@ export const createPackagePolicyHandler: FleetRequestHandler< savedObjectsClient: soClient, pkgName: pkg.name, pkgVersion: pkg.version, + ignoreUnverified: force, }); newPackagePolicy = simplifiedPackagePolicytoNewPackagePolicy(newPolicy, pkgInfo); } else { diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index c333ba9f7bc3d..b0aaa64a69239 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -125,12 +125,14 @@ export async function getPackageInfo({ pkgName, pkgVersion, skipArchive = false, + ignoreUnverified = false, }: { savedObjectsClient: SavedObjectsClientContract; pkgName: string; pkgVersion: string; /** Avoid loading the registry archive into the cache (only use for performance reasons). Defaults to `false` */ skipArchive?: boolean; + ignoreUnverified?: boolean; }): Promise { const [savedObject, latestPackage] = await Promise.all([ getInstallationObject({ savedObjectsClient, pkgName }), @@ -169,6 +171,7 @@ export async function getPackageInfo({ savedObjectsClient, installedPkg: savedObject?.attributes, getPkgInfoFromArchive: packageInfo?.type === 'input', + ignoreUnverified, })); } @@ -239,6 +242,7 @@ export async function getPackageFromSource(options: { installedPkg?: Installation; savedObjectsClient: SavedObjectsClientContract; getPkgInfoFromArchive?: boolean; + ignoreUnverified?: boolean; }): Promise { const logger = appContextService.getLogger(); const { @@ -247,6 +251,7 @@ export async function getPackageFromSource(options: { installedPkg, savedObjectsClient, getPkgInfoFromArchive = true, + ignoreUnverified = false, } = options; let res: GetPackageResponse; @@ -290,7 +295,10 @@ export async function getPackageFromSource(options: { } } else { // else package is not installed or installed and missing from cache and storage and installed from registry - res = await Registry.getRegistryPackage(pkgName, pkgVersion, { getPkgInfoFromArchive }); + res = await Registry.getRegistryPackage(pkgName, pkgVersion, { + getPkgInfoFromArchive, + ignoreUnverified, + }); logger.debug(`retrieved uninstalled package ${pkgName}-${pkgVersion} from registry`); } if (!res) { diff --git a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts index 1385c110f2e4e..f69576a2a8b56 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts @@ -35,6 +35,9 @@ export const GetInfoRequestSchema = { pkgName: schema.string(), pkgVersion: schema.maybe(schema.string()), }), + query: schema.object({ + ignoreUnverified: schema.maybe(schema.boolean()), + }), }; export const GetInfoRequestSchemaDeprecated = { diff --git a/x-pack/test/fleet_api_integration/apis/epm/get.ts b/x-pack/test/fleet_api_integration/apis/epm/get.ts index a030a988656b9..2a63e1c8b3905 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/get.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/get.ts @@ -144,5 +144,18 @@ export default function (providerContext: FtrProviderContext) { expect(packageInfo.name).to.equal('apache'); await uninstallPackage(testPkgName, testPkgVersion); }); + describe('Pkg verification', () => { + it('should return validation error for unverified input only pkg', async function () { + const res = await supertest.get(`/api/fleet/epm/packages/input_only/0.1.0`).expect(400); + const error = res.body; + + expect(error?.attributes?.type).to.equal('verification_failed'); + }); + it('should not return validation error for unverified input only pkg if ignoreUnverified is true', async function () { + await supertest + .get(`/api/fleet/epm/packages/input_only/0.1.0?ignoreUnverified=true`) + .expect(200); + }); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/agent/input/input.yml.hbs b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/agent/input/input.yml.hbs new file mode 100644 index 0000000000000..1ba86fa98a2f8 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/agent/input/input.yml.hbs @@ -0,0 +1,18 @@ +paths: +{{#each paths}} + - {{this}} +{{/each}} + +{{#if tags}} +tags: +{{#each tags as |tag i|}} + - {{tag}} +{{/each}} +{{/if}} + +{{#if pipeline}} +pipeline: {{pipeline}} +{{/if}} + +data_stream: + dataset: {{data_stream.dataset}} \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/changelog.yml b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/changelog.yml new file mode 100644 index 0000000000000..d122ea7a8e6ba --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/changelog.yml @@ -0,0 +1,6 @@ +# newer versions go on top +- version: "0.1.0" + changes: + - description: Initial draft of the package + type: enhancement + link: https://github.com/elastic/package-spec/pull/325 diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/docs/README.md b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/docs/README.md new file mode 100644 index 0000000000000..9f29c89e0f5ef --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/docs/README.md @@ -0,0 +1 @@ +# Custom Logs \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/fields/input.yml b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/fields/input.yml new file mode 100644 index 0000000000000..f5851c64b6b3a --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/fields/input.yml @@ -0,0 +1,4 @@ +- name: input.name + type: constant_keyword + description: Sample field to be added. + value: logs \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/img/sample-logo.svg b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/img/sample-logo.svg new file mode 100644 index 0000000000000..6268dd88f3b3d --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/img/sample-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/img/sample-screenshot.png b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/img/sample-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a56a3ecc078c38636698cefba33f86291dd178 GIT binary patch literal 18849 zcmeEu^S~#!E#4Tq;}?6chqwB{?k=6jc5D4>l%v(rleJ2Y%tW zDj9g7px}|*e;{M?LDwiK3@FNS(lDRTd-MJYIyUJCN948~OJk1M(DrJyI#iV;P4k~& zFZo35IfQt0RwlUN`48^6(1dv_wm(y1xhEdMld=Y?!%u=fPT_*{3( zwBwz3#qR}_)t>C*jp5@U)Ti~B)Y;qq*TRxZJ7ZRN_^A3TDAEM*@7Ve%(Ro7=1%1B< zVj6GBUTxXev>_^SFA zgKZ=g4aTS}9>Ofj7cSB0WO?gQ)x=+!hs_)b$6#>ScFZ>XAoIX)%Bc|BDC~JFBk0f0 z0NY}6gb)&!qx^FWC(!ji+Kl$V$2|ocA=vN0TM0Y`U?tX+T)c*C zA!IL(T2Vm%MCLa85^if@J@Kkprx8QN5!6eCR@4Oa5S?4-4|ou?90mFCM8D!;n(5xz zO}-*t!TntN>|a$s(kGQg1P-U?hqvGF2_fGvd&~yZ_l3Qf&j~XWa=;>N3#-~#zjzcc z*m18L`A-K2o!d@J>a8SRbm4P&-q1(H>|JgIymDbnJF&@008`=X!P?4DGgZb>voUl^ zNJKgPR4S={)3vuk_{n@=M8q;;aJL>q+VLdTnO=}`&x;1DKjJA3*f*idS{jP5?+;!W zn-^7021Z4zv`Aq`hmX1aid997RNh3fa-@PG(W7TzKa1W&5^y3|lPeETP7j9qXpo4)7%(W0_2 z^Nmq;t@rb1eP3?%kOkH`P%!zTC7ZHjSfNN3*Sb#=3#jB*KpNGNfnRZ{N(6DrW(;B2Bwom<%m?VQP%K+ zsFeF1-(DY}oP@)w^Kw~gPg03q?N;)Ec6^|nikA34T~RynX*z}H>R~qgT$`Zbhn8wzZs$j2fsGN&rOK-mIBBvzD@a8FgbLpL!h5N^u&0wG} zq!#md3MHITv?3@$37J?lc_5*LWJTTjel;IiU-Yq;(g9I^D&KN_NKVS0O~GvB~FzPM6}=4d%fG4Nw4pZshcyLqK@`b8?RhD38haIyr@+8+0r5TC1*C7^WleJ zZN3_ngTD#RQvNL*;qD2H@cBWJbCC#d!}=oKfod5SE9a?!?j%DVt1z@inN}Iy$r+96 zM@P?AC+(`cM;z6J94BYGJ;+P-N#yj$?`G26ydS&OVH?~JY(N4l()Fh+x+DoJ@r<+i zhm^ck@QP`=fLApr62@KyOef~}zuG;(VbDQmw|Wb+oSHSw=%w9R)=et0cY*~ytX)#M zEXlK^p;zM@vTnXn+C1vwP)~TJv|TvDE2($;;EzC5_5IL#H;u z)#CO8)TSzbt8)wHB8$I8KcIojx&GoE)3QNu{CQ+_xBmQ&`mL5-u=BX(hs^hMY^ zae!!*Q;Tr$@(0~GoBJAohGw*d{l8~!aXop87aaSUb2jm)Tk>#$1*cdo5Sl+?oD!l4Og~yX+soottl4 zp4OartUuAN(dD~yLJ}`A1*!D4-|L^hM;`_DM^1KYs-VF(}h(BjRO``b+xV~%O=-)?p z7ciJH7Fnl?V&=ay_AB{oQoa2iR;6$^tiE|-eRCFy|3F@%j#6gUxkZX@?K`F$u#;T< z4IZORpUthmB?U`;zrOkp?P(Rvd5TFRWrBJmVg;KEZvJ+;Q}FRY%QZ?c^&$oPXW+C5 zdN#c>v%U?QuE+hMQdzxS1Q(BT90;29qu#^A?a^)Ui;{TJ;%`nLgm2ew$J4NvREjCJ z$`C7&?tH$CrVG@M3J1-KJw_*9BKeL*JX{ zN+Vg_TXb9^jJO$ZGkXO6BBFDjt~w5`w2TB*z$&1W5Il3IiDs=ZMDt|9iRtKET*wF6 z0Z+|N87p-5Fh)^(*l>OVr5^aY5LW(@PuM>Qo@&)yj6XRkPm1>eTF#Y_c*aRF^ZY5A z9FAU7lKEHG@i{wJMPg;n6z2|69d-)q9@<7t()d-zPy&X zdXG7{Uw{k23)CzzQAXw#iqj<1u~W@K_Ljc#?ukh;fRKHeJ2l~Z+52b2n^bGiDF2oX zm25FLx|4AP8>rAi@koY03lrtS#X?zK591c?2iZ_jjc>0y>q9>fU<08o6zG%z9WK+S zDwZMW4~28wu#ye#V*@#5t^S@NiAA`3{SF$xINmc_WW^u-C9M=H>RQ1>WM=|R!660{ z6E6%DwX`eu<3pkmz7Z=FCRd$(vhDkc3yMnSr)5C*aho)DZ<12$`$TXj<8Z70)|rK7 zXFD8QzksfWZU`qL2K8X{C~TcF{KVW`3Y{IMb&)T9%1V`tv(HY1 z+LXkLyM|3mtLD{x-#hOw-U?sr-iLeHFA|=-sGZ4#hX)atL!a91(tWJc+og&5W}VfZ zpgE7`{5D`~?yGR++y7~xA&eU0N*ZezDjF$> zUeK&1aTFQRg*?v^Z2e7u<`lk$czR6}b6Cl-qA9%A`#A6q0*zyTu)X`3rhjR86NK3= zLdw{+-F}+b2gxd-qF7>Rla}dFkj|L#c|pg5Ni+MRA|BZH(@ME*o<1ijKcoXb%PVfJ ztp_uf=G%kvU((pHcw90Xut=}atA!giM-5By)f40nKp zv7Wdb{;^<}VRvruH~rYr~wEuYY2ov-5Q|p@u3Da9+z7PeIpBAwi?RxnxN3Kt+N9L(LUS%wxY` z>e&1VV;{CYw8DNRlvBH)>!I49SU4R!t3I4=y;mCevPZh!-}~G+F>6hcL_Rli4r zC4(WN)`j$>^S=~GMGR=^)A6wrqi(-x{xK37&Vx!OS6t=KQ2JVZo#GrSODtTe=TVh%*qfF%91nqsMNLNL^Gp|_ zz%I*HUkMQGqb!1eh{{bp|0GSCDbkG_D_d)8<(0r<6-%Qi7qDa7xZjcdZ$?Rth9L!f z$erCcs3<~mtupywbaT8NWZF#v?iZkvqSz3@p`RiXs7P!GUa~-U9hEG(NgI#3BzO-# z!9JWf(;r!*A=@g$f}>wi|6Q@9z8AmYf~x8G%sp>C5cfuJY;hs1o3Ozu^{pH0AFbs%yU)Xy5>Cf?qXiHn*-PAfKDRiy`U0sFSKFsgEZ6_ z9#ma!<#Izr^}_z*>PRSt564u6We*XmZUx^jv*dK; z4zyFZ*ZFSE!00<6!|+#33&R)@RA8V9YRjp$HS9?CGq*xDSDRbX#i;}mateEF{fqTI zt?X}Efkq_Ap*_ETgaikOBbQ|;47}hwX44K`(DUI@C)QiG&6UJ1UmRn*Q@6%e`+x(gpQp74O{;yli8YLCV}qD z4gIyZd_(8ED~WWaeXOb0^r=9=AiDT}by~+$KVF~M{ywbQl zng-h?a_E;yX?DCr4|_h7JMc7>xgWf7Ek-VmH^hCYunVp3{(d{---&%-GZ=rK#V5Jo zJvP8b!2AA5?9)G8gwzB6ze3TU<5*Pqms^Q-?C9-CN~4hb-`U0D@kAkTWn23``cao^ z8IWAp8h7`%ZA+eI?w$sJktq5m>e&0@mQn>2BdpKAxbj1$m$8Z;`!iFvl9($Lb9Ff? zT^6cTZ~HgIeR6R*;G(rzpgsJP41Fx9Df;G6{;k6T(i}&8hX(jHSC@~#X@70h#)g(( z*9vUC+a*b%oAdf1$}Z3NR;|c5nY4^Z51pfqk(tmJbB;Q#ka#tf5eae;-kq$I{xO3<(TI$0lSe-JQzJ*es;il=Kn_?&?E zfLbs{qErPqm)-*ZfwbA*D-shgb|1;X;cH*yA|q8gS=HiosF=-kbdk6--SR+`F^H_` z0*i`J==@XSe=HT;_``G}ulE=H@*3GU*?gVd@h*`eT^GKjI;C@8+h~;(u3bA#b&bN{ zYw>dJ$(;RfHDLlndS`CWOE=g0jOocCc&;w(dOzrLf4-DK*MD@P_;u&CbfMw=#Q-B` zDq8hGwKN-O7(hQA_bP3f5XrZH+@*FGw~ppmDgNWcf|Lf*Pc%e5dw1DcJ1BWm!z7z3 zr^toEU*P(>G#;_1X}Rz(5lbDtCui%hY^d3lm)kw0vyk zX~K4$AG#7cG`6s2%9g9zsaQ9o?;3yzW4Pt!;NlS zzI#G7tiq&@eV&}qDtY(e$1JwscAfle%Al{3>Nr%``n?`Jac^CdOXUbFgI3;m{RkA~ zokl+lxuw9=%W&MmzA+G%ZdFMMP&N2^6BWjG2Lt|xKx)lMCR@b0n+xgw<)&Dwi?}>- z+$_e|@M;uW@3z6)q&L7bYitZ%huzGqH_qHOr&G5o!?(8TJv_MN1ka|&c6_!Q>#PgHSFoPWiLg|k_{ zQd#Zy&BPkU(0OE5S35!B5qb6%T3Wd#J(zBl8dw6I#xIDDF-LBPi-jXv1E?!gE|1OIdTejK)+U3ooC^otSIRsWZf-`&K}6}s!407Y58zH zK(oYx*7sN1O|Z_1YIJS_H$E@DH(hB4QKNCGQT3PTvwYoe2&8WKi5`5tU-r4!>_V3XUT}N)>8V;+z-!@-IGCKiD>E9RC(K`NMx=;Qp zf$2g^t?)zpU0L!BZi(oE#)^Z_biT*Svh>r#%1=O+Wo37G`Q)4@k#Pe?^mgBIugC)8 zyEICH=`{A~^x#X&%tr-$j|(nXrIrGQYNY+C3M+LO;yUU4-|v>a5#P)XYp>_|C0f0n{_p0mvwWmghfd%!Cm}$qBDxOqA3htLs~ghSA1>6^dVgd~ zVHHBBy6;Pp=El;dkTE=ttp~BoOJ$L@EB3Z37T1kTNG3tm4PY5O-7hP5DA$-k=vV&6 z?RiAm;W~*o)R7!x9>u$&@|&D4xMmJ*y+^-6t!F0u8G~78t&Bs#W>w_NbW>W9M3tXWXRf zI86FWVx%iXXh6MJ>dg#?lNu{K@S#nzMIG4PXQd%!Bvc*H0c7F_Y=adptJr*cHevMQ z%?Xu~q8CFw>^L*S_83kVhq=)hf0%_Lq}SE*g(Da_A{kXVZfAd*YCwp~bG32wi&SNM z#QZ7}Ug5-=+s^uqAh_|}gzya<(&E?XAZ%0ybd9nraj?|z1YfPr*{N?Q{ji}YG`T#| z=uwJZHIMlsmevnenT#-)t$L*=2wh|1EYXW?_36TR?L!sUItJVxaC0$Gb|gq4{|4gA z(v0ODFj!T)jc5>65ys)* z7$aBHfbKdz@QJq1b`NT`344*g()$>5*Ey`TPB7WI;|_8o8t9-_4ikFub|I{66>ge> zHA+6onzFKY*eaiA!77SD*^&LyumAR6gSvxY6Q?;!AvI{rZ##!G$%ZfIgce4F`aF;e z?jVh%+B-vj69ei~bh_zA9w}S4B4rzRKQ1~u$gwVu_x5PlRKDXX2(_2Mm7fs%6{SS7Qh1gWT8xaxc=f8`mW38ukIZxwU;lmHABwFSg50*o zrj%f%j~IKR?N5Dxwrq|sTa?!pd{b3sFM&~{4~_^YH4$bI^Fq2W4-y`))^|7fS?i0) zJ&Z9wY!8%l7@gAr`2{fqA;L;ptQR*X2|xUtrT47KK%XN+dydN$*M?65LuXTRabgERR{n>;E;(&vS0_@COY!p<%5LsRqGpER%~YjkSK zwBo9-2|-ZFiU3TT&S+@}3gDT35t0IXTzX@yHA(v>Y8;-mZNySQ&fE7RJ1^tzJfvdApX& z*!+tE)Y{oR%jk8A)3EiI3i*(TOwP!;B3hAOj?KQ6^h-q~1V^166uYS~mH*2Hh*0}r z`R3u1#^LG9IW|^QT^|61H(T1Jz?n;(Z>52lU0BO>Q6*zgpP*gTFk2Uw)!3zt>3F~_ ztil4!R*-j}wjh%&(kSB%}X=u4RbFRp@^l+$SmM@nW9B;yGbf@nasjFMEE{m9Oe

}qal5$moSACwfNXLXG5|3R0AtBcN` z?%yS)&>O>sqxU64U~C3&Q^>z-Zt}WuX4Wh3dKj9EO zfSbV!c3e;EOeKHQmWEw#NM4;*tw-2o@x&kKT?rsmy-F|$jw-F>WgA7?C@{O1qPg*J zf92|RTBMh&ptHADFc{T+cB?+mOj>h2HKgwkxq6w&XBxPc?>=JKvU2K9aU93@vp-R% z{5T=P$9U}AYZ5QU{3%7}YZ+ACWXw#-U zWyxU(OP#Q9-2AeGmCwcp`zWghf2hvsOjWjDQbU?U`v0&a--f1`v0Bd8HLiLmo)PKz5!A1|XVO+89 zm3h2~6yI~cpWor!_yt-?Lt>z`c0a7cJAW)#d8N8nNIf0H<+v;s4{0guDD(?T7Z<~$ zd`$vpZ_QQgFaMT0_d5&+(jwGU?M1FqUu6wjA-9z?mRM}(CmSdK;2e$Na}F-8jbhgN z9)@AIQeghf{xCC^{9P%VdYW1PP#}2BJwWt z0Hd8%st1NK5%h+)UB^mVwh{e#8TIm$xxgGo6I5;e{~VUeeMGRpM_Z%=eH5$X1}?Z5 z`|*_Vp~K&ziz45-Ih9y>EOr(Buy0&n$dbQ4$5eSr=Ti z#~7^n8dmem;$0D4+6eV7&G2D~d@ z+R#u8+nw_N%7_U_1e53P?~&10^m|ZUXrZhVp04lQLsGos%0fRDhS=@>8TOAAxK;Cy z9GZw_1pfSxD5~xoR!INI?tU0wrKDd6^Tv{jL>`Xb49kBaNPlhMaIfh_nq_)zB7NcX z05XeQKz`@BDUx7*i!V~%dc8XQ#ngBw0A2tSr(npSCrNy5Z7>48v&Zz?0{%FRElh_h zN2|?#EhJL5HQMIu6m1=ypTR?tVymHK)xQvS9ir7FzMp?CjlND39PK`od#GytVhZWp zQ1@>MTE1*Ip>hnXSWa?XbMH#708@j12yPbm`JfcqIgmJepn$5YgkJn_%5I)mr`Q(k z-a0yFR3A`houhvf&|wNpIsV{2p%MqhR@`@R(l6`}iufEgI*UxWq~26?WTpZCV{JtG zYL?&#I98fyf_;2S0?_V{=Aa4t^x%vy$pF$_Lh7W2f*~5uPvGYh;vZhMv|u+Z?2t0~ zcYPXdxbg6OS*LUjR_=jLDt)ab6;?g1IuySLG@UE;jLpt-wjLX&RlY>fnd@f&?0NyT zht5vhP^};k6`U76$%&I)iWPNxG6KPjdh`S6>g9GN@;KObQsLG zKyjfrPR0PU1B0a0=)3@9eCDl?mB9rFdlTMtTAeZv2}F*|@JWleq2+H1bt>>x!^wTk z+I)cgsZwzCMwoRpW_*!3IySTQu!`HWugAXe(Ai(a9Rsu;*0#o6torxwNMxPzEAjt` z>70Vw;HCQ?AnP`RKQ;2R8h%;LI#tx^(MO*lMWJe4_?)Q571P`kTmN#(ez21V!<6+S z@Uap+y%#8&cGgdf+E@y$dUx3g#)=#5k31Vqv0p!%L`*=-PiQAiSg-d9lKRZQDuJ-| zA96zwwomG+4}X$vR*IU=NC!vL<`rUTbf_uRJC4FS;k&HtV<=<)p(qymH)=MDV^aqK z#%sid7K|~!H`J!7hRr~Z!emxgWq6#GpQs%c#BM+scvNGz|Gi4G`;8Z~dP8)+51iB8 zw)0fazNz5(iK$LJeC_4e^8&@wT(DZ~~>SStz3P(>V8CLNlZqgv=2K-|Lu~si@XFwMN>QE^k zVS2U_A?Q$?M`NkU}^!M8m%O&T=kW>dG}1s2I~hxp9Y=a=1XX-(fB5) zej3`e5Et~R^r%?CZK0)UZsF_+tSOGIBMdrtMf#oJjGF9U`*P8t>i*TWed$Z2WNUZ* z_1Qw4Yr+Q0@bD?hD0P-^v}?FpPBg~zz5~g@J#J76C695|P>1l;OS8%~hZh5&-9Ji# z50%&56ZK4FC9}{jHL0!=qo9Yd(GGHCEX2|-F(f}q6@NMT4P3rQd{Q!=bz-8N(Z^!N;;ZzAWRf@C?X>mG=_NgyQX_?Jv$m(9$W>P;+e}O|&w&DjbsJPdWp0A2$yLr*!BY73Z z5d*BCaTI)w=sTlofc>n}@v_tSXIK?8(g`G_06u>SD*fOZJ~visq3lBVS2+cf-r$UQ zZ(8A0g&5M$IV7w5nqL(m$VS0X?=yy-e6>S>Ca3wZNT)b{GF39_gJdONflqc-j$b~o z2l@@h{$KVfC)V?#We*)@xYC;L^<@cHo>8axRMbSzw|eYTl|8pkabsQJ(3`z{>5H}c z`psz_Y6t)hvzL^=}P#++XUl6v`-j)SuXd6BynjNZ!&c2hnyE&4*K$nXn31Zk)cm+lx;> zya{T?{MRtSu?^3Y9bS&O$*mW^vRUpv!J3Tz12?3&Y62b_oiZ$24O(75Z)JWb+Rj)ACbK`f<&tSwtT$|Sy z$41kRPiM-jnPY9PKrLyI`pHm6LusMsrO*HpmE){Kp1^u2t%6nW^;GB|!4k!Ik8oav zjM?DBKh9G@W0gEwiU-M}0B)}olvoM71RccgiZBCs)L?q_GX&JDhegx4k2&cNatr5w zU)1#2USb8&`etO5Vk z?0}K+*2*@a5yt*X{qg0@8jEz~jcylVj>-042p1PBnabI#xUiCRD!ouw3?u-wwsqwF z8(@m8-Lk7q@v154g6yvx_tRDa>}oqpVda)wfI9(;ZVGt1v^{<|X?vC_(i@IJC+2I_lusrT=$h zF1lPc*Neb`;Xgrdf`p$w)~MzQW0M3_FYRKu{2$VU82J^B=X1#^<&P$_`=S$Ey04WU zTxG;hrFNLhWC*p+sH3x=JVcBJ9*7>eO20)n671SxQhZQlHMRP8FyO}yai~OTsbms0 zQ3b$C1Cn!>jMHDq{VX1ab^~_Q!z+f75+_AuwiN0*wA_#M#0|rU{+NlB%>Y+TNT0Gj z`3^LKMSJjz2(?lwg~ixDl_5%rzzZ}o_6Fj9e)T7gpH4=BgT1zmwJpC@g(f%&0`}8B z%7Y&qlP3aFmI#nmT`|R3+Lwzp+PLXt|5g%vlY_$fvse7zjus0D0fA##r+i4G4K-2Y zC#H95NGoYfWP#ZF_v$^Li{PZpm}fc&)aL?5doPcb835Cr6`T+EzzcEvLtmXcbAb<^ zw!_Zgk6Az7YA@*vb)(G{_W-B|zrf76z^`X%jOgqIIaqi~5nUup3vugzzg&rA^w(zR z+qCzvIV~nGR=47pDOcNTzuBw#5a=<=DMvGa)g zPw$^pmq9Fg&b#BZrPSoml(149rZS!fioV*Dy$z440U3MXDJmI?RZqLy0}IKSxN)o( z8+8wIZs#q(|KTg6y;Z(=96>xfpUsr@SP}I^v zN^R;ZVrDaWmNrM5-<X@k6JyjvA3;jHhma|Y|7!Vk& zgf(UK_6~cC;!|b!YTjke=nBiUqQdb#I9TY}!s5P)H+^c;9cW(QO8O%n5J^8Xfktd*qrn)+?-gP`m%B&q zi^}7jKm`yMW8ITFOMN#!QIB6$SWx*75tnCMaNg*_J*WuwBh~AT>0($nS8%&zmFQDp z$dL65niDtTV%!Kg1`6epWoQGNG`$`doy;Zjaa`keyL0F6iJMae6FIgnhAfzU%m@V+ zm5rQihLwS~b6{-bVR1ZSzBI7(Yj+V6T-8V*7I`ptWArGdy~8pnV>fALpi~NQLZ7;^ zpaj35=md<~-(tNmF69UX3?ua}A7UIn)q5i1iPYEGlhYSbkfeX`5epkxtzk3Qbu| zlgA`7ts%IvF4HJ}-98akyRnjCo{u-`A4&b+r?s|o`4wdYAHs-yh91p$7C_|+EdYH5 z10`!*=n+W9g>V&dfU1H!J}ASZi&-?`2IlDOAHnu306rD`y>jT)4^@S(X4XhN2{g9i zj-ym98+RT|d0ejIFJCM5>S{mT-8uGmRRqkJ3sMO_AQDrv77Q zv$t>zaVpVF6eBguE%9M2u?E-Oleft8z5+~W`G}KXD(Yc;7m4{Op>Le(k`g1UK7(1# zt6g}$n=Tdn{T4pu>v!c;xRCd_WI$Ali13x=U_0T!Ga-U~9W88q-lU+RLn2`N8Ouho z^0@SvC>$DguHWx)?^*ms-{PVq%dn(U3vrLj9zITDqQZ`H>Wsp@Gf%}SG=m)Vh}F$ztQAbwVGdDgd!28j&yX9wLW&s! zNR~6`nYg;ULAq8zi<;gUchAV5ib67Y##l2 zy+%gaD(|~G4@||{A;TYDSoS>q2o{t23t-^!NDSDEm8j3ao7Ei>KYLEpb$jz}7ciAM zD}trDN+AVVT_lXW<++~>8>Cj8fzJo@R;>%nGq)6+w?(#mNc#1J4W+!hA}?g$0Xqo? zn67qJmss)e%k(xO*&K@z6+}nHA(lCkb6n-|{pSztys$8HiOWTVR)tCO*Q9~if%3n7`uxGzE+OCu zwcVV|tgQdq60952$>85-GHk$lwM(uI+CU1?i{sVnKd0+UNq#eSSKjUKfDDgLnBG1y z^v?f#MRFkph~TgkoKBvM`L_~we8__xpLcjh`GwV|87q`vazJq?SX=mXhdvK>VqUf~ z4sYoTIpt5S)KrE-?>&=cRoBumD7;b5pq!Y07)#I$`)<@U+mo*dE*P~773p*u^6waO z2#thJahX_ySlYMpjx%h<)i43ao~Is`^Ya zMNZkuChEA7+ZJe6$>-C*dzTYf3#1SY82yFG?S&Q)5rTbKS-XLjckTLEc7>^sFcntQ zBeNXCSg&q1N3Bi^4zlQ%mcEBQ%2ab$?(;t-$HYd2%cnX$uuwU#I_6D3($m zR(>gHzM9ODf;r8b0l5LuEIQVZiQ0-|3Y_xzJkZc*CD=bPJ+&J+>>se%D4uTq?Ny{l z0Z5~og*Wa1O&anlcRWu_%o)(x?IZ0CfUNk_R-ik>GyvdFmpu1wHZaKTDGhL zqxsji)n<+)VKbV0_BRq9E;Kb`f=&vn(BK0Ba-gL?ZN;^^b3YFg6R=!q#zM;tcX0dM zdy5PPx@6pJPXHzH7$dGjM|6@6777nXPWV;CIQdNf(*Znv)sMy&Xcq> zhCq+6h6&v8<0}vd2(sKqU3j>fr7&#Xy%qZHcMU3m{wld^Nstkz8GagB?Y=SI&H z&{&BSA-|(i35$9(l6LpFyLm$0M0fK`Dz!~ezL?yEInsXAFR!bHe;ZL>Gd(#Hv?<$%`^b)oi?x%(jkylCPb=juPlF znMo&o961=NZ_$gd{xp1ZY2dNDOS!=XVj!M^A z+$z`EK4v=m{Bs{&I4W)({`&<5*^BV#z{IBAI_d+9Qx;~ zby?2zEjzUUeZWBDo5cz>%;z||z)<+6UtC)y60yD5J5`oo_zSM;l21@CY<0_|)NME5 zs)kHCMBa5YzB#N=W2aR?y9((~WuYwwf+HAc2mvU>NYlxOTvGf^Ye3za?*f-qUs^`a zT3>RPh9*Jf%3*bf|kqtnD_Buxv!<9N>BbuD#uYv-q^ z%RDnd7a3O4M9Y~TNISS@9K}JDkdg@>x8E6@n8jF=6qiDV+}{!V)(o?ykcr0sxBGEx zo!X;pc=r{H^vw6ztV5VZXBa4~(ujB$rZQ|AaGN@J7#q%2nU9gJ)g6dcj}zYB1& z@iFE0vMQVxa|v7tDHS$gwX$Ihc#M^DXRC>J@Zk?dC(3uB_s~*W&m-01DFMQGWjj5x z5po1@1gPl!v1Yra@qPG{D;$bYLM3qOwpl~7f~l)#n< zP+6`!NYe3EE~4RFR#_e=7YctPRBt6$He@`%e5m}f$M%yzC2S0<1}hRPjO>HJY~ z*dx(nbMbjv*;o&k{qzBdF|lS;UNVKziV=gbLq}UOCwr8GT5E9oRYQ}+>DhbQ1R=lj zgcNJN8|D)$Mx3#c+t@lhqcDUnHGVt0&EyQ{b5)=52B(VTzw=pQ^ba3`JB@BU^lS`_ zJEiLzgU#Acd_!}FMxCWC**FP^i#P}bYzNs78)#uSejEtYLbG>JJ7Igtho2oKQ;XW~ z4eMGO+t!_;G^V6c&R`5Tg+Pz2ToN(aybq4Q0ssie_{`t*DO%V7FaZ`{MBobFc9|pV z70o5ayHGJo9$$&Pgbs)pWNzduAcbh?~U?_P)(ve0S*3H%eNF&a5XR=!J#4c z;t992n7ZJr{*%`^dU1d-ALE8!3i#v;3r4r%j+JFCe=%3Vj=8{aXe zs)jrcUBZ=;LudcTUXj2ub>K5!{HHFHJ}Trx(PYugbQ8yK7&sqX;(;|UWjk3tGs3zuceeX)i4i_jA8Qz2Bc%DxN8 zXw!$+9jBtEHd1y90bYG4f8DcJM)Ab!M39tH5zz94*MAvnhA377@buNupSOUU3j8~> zd6&hk^ENRCp9T?_QUHk<=(&9Q^MJ^pi;nKOYNR@?L=RCSmKMJ5UQJQ`X!i~(gD*P! zs`RobzJG3Ra_Pg+WZUXUmMU$ilpwfcEti6)mw(~MZ0q!^sza>#jv!-+7B6F3QuMWg zVO!rXwD+lF1BBTito?ml-CV3vxuek~TKuOX^N6sol$v*{_%nAuD7i81eXm^Lz(Z~I z2Xj_Dts#G0&C;PV_Wkq*1QvB7+Post4={v;gk7b9u%#DC_bh(iJm$rqog^{JEx6NE zrs5^2SEL$|98#2WV#iG@L6cq|)SuTMSfGocPl65wUd^|5Lbpnb(;t>-Qu2jvANLgv zdte0vED-3C@^BdyHWLL(7{G$WA02z@JG!T-U^Q7HZ(7Bs&vchkh(p&}KvnS{MG^i6 z4r){gJp9p7WyWOEiKA2Cm6EXIn&&gk|Fc6^78OpPrX4ExCFE=SD$xcH;C2eB^{XTI zaxz_Cef*Yj==w_i_BTGXP;8C&f? z*QEM>={jFM8)lWAR870pG4XEWsl%%K|82S5b=9hVz7p_6i-d(Iyvq76&a#PV zR;VbQV|n?mg}&(ehClg%tK%IjgtnTR-u)lxH06XxXqH0soAZbB_Rm)XX=6Nge1uoG7 z9vQM_S~2h53n|W`y{{R9+=08rv~MohI_v4-BU^7fZ0-A}#b5{AOSTJm+(J;9yw%pD zX6u62GJ&@HKX5zQwq~j8T!Hrv-Mk^QSB5cu09L03{ToDO7jikM0WAcsjW>D}^jqCF zT0DEZ@K^KO_MD*%M!+V)lGVU6?LpX)eQVXEmq}R`NIJv;kBitJ!nW?0OxTVlu2ADf zE{A!*0g3%nwVcBD+AgT5bGx@WOnQk{zRpiZ4HhP`3BF%N|HdqPbbiV5)7x)kzC3ID zZ;27>0^mrMgWc7evsbQY`l`l})wr+e;=8U_!2&B77;1qL!N8y)eTJ2lf#CvhR~!Qa mc;sM|90DP5A*JW%f2r=u1xt!e4gwD_V(@hJb6Mw<&;$SznOm^{ literal 0 HcmV?d00001 diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/manifest.yml new file mode 100644 index 0000000000000..30533c4911fed --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/src/input_only-0.1.0/manifest.yml @@ -0,0 +1,45 @@ +format_version: 1.0.0 +name: input_only +title: Custom Logs +description: >- + Read lines from active log files with Elastic Agent. +type: input +version: 0.1.0 +license: basic +categories: + - custom +policy_templates: + - name: first_policy_template + type: logs + title: Custom log file + description: Collect your custom log files. + input: logfile + template_path: input.yml.hbs + vars: + - name: paths + type: text + title: Paths + multi: true + required: true + show_user: true + - name: tags + type: text + title: Tags + multi: true + required: true + show_user: false + - name: ignore_older + type: text + title: Ignore events older than + required: false + default: 72h +icons: + - src: "/img/sample-logo.svg" + type: "image/svg+xml" +screenshots: + - src: "/img/sample-screenshot.png" + title: "Sample screenshot" + size: "600x600" + type: "image/png" +owner: + github: elastic/integrations \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/zips/input_only_unverified-0.1.0.zip b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/zips/input_only_unverified-0.1.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..de9bdbb141980836b59904cd867161dc134d2de4 GIT binary patch literal 30629 zcmeFYcT`l%);LI$vkgj=&?Ez)fu_khM+M0s2n|h?oHMONkt9e|5D=6cMH)d#k~0X1 zf{KVDQ6)*9YV_Ur-u>>K-}l$7nOXNNPSxq!wX1fjUAqE$+607W@Nkbo7~JUO<99-X zM~3I*=HcsOYd<`{skWMU*W-346F=%+`a7nXaHbB zlzh>`cz96oiE9X#H~ZAGogW|L*y(;D6CCF`hl16X4qg^#A9+aXkJP{6G7@ zbN-M1|5WGSH2htizo3HvP~nQ_@Za3)bpr~1L;kbxBJn@^{sa2&UjHZbzx%TWjsEle zBY}S;@Q(y=b2jcFrTCTqll~)te1>j|Bdaz<*1C;MY$mZvI#O`}O~SBmML19|`;;f&X7g z079r@prQm=`aQS)59V-lEeyQY;Ke<-dYE7NA1L7CWGV)AaZ@oPcuyWs4#RzbT;X?) z`IUnb@ca`9oQUC{OKaM#(P(F^{QslwGTy`j1N7%{F z&`@$1OaK-f?BnR<4Soa%3*vy_3s=v{9_E8`z?I{&f1~1l!BF0?5byzW3i)>sE>%eeM>ce0@fgW~JFgrIui>;k2FsI+;Kw{UWV2(aM9^O)df(}kT zj=nZ@haLFg>*69Pf)FLgi6q}keEJ0t2k!lQgQov0k)Yje zz5h41$o{v;`l^a5msH`d=>HI?vah#~yDLn`-N742-@g9Cceqmx-23HXk9RD}ye+-mAXcU0CpZjkZI>K}A25i!W#unAi#9dPkaXYyi`^_wN~}`zy+wTpj*5dg1;% zT<;Sq1pp=PaBn|{KNyz*KVbe&Xdg#eP7wqr%+b!t!O`c}x4n~#i!7&`yPF*+%+JZr zU&%c{mQx5O1QS7kKTcSHtBaerEGN!Jfr!bYE22m}P^pu8MFyY}w3zTPMs7du%_dz6beDDiT~{Q&%O!cbmLC;>+&AWb(} zP9HB{J5D(noc{vC#!<$lrl!UTL(6hr0t5+*!NtW0VAh6^JFMBrjb zVNi;Yl=z*Vz(n9e2mu5fAWOo90O(hG0)k73iwKCqCB;M)L8&MXBnlW85<(#0qM#?F z7zz{#iQ@nuJ;4FhC6NMfq_8BeROAE((i0dGE-3;Nfg_P(FeF@DLh^U|8&6z904^l1 zh=fashyVyK#X*p8;S;J5VmQ7ePWS@p2@;@PL=*;y7f}?0BN2ctkl-LfFkw+R;-p06 zglSxg1K=bf3KN!qOX6As?EFe`AY5aTxW*8|fOMP$f2Aiq!G*IFhV{+7?br6dd&6Gs4DiT>hQLIlScNO3*k7&}q1h%in}Kr_G66WDK? z2?9n1oT-oFpKME2SyUML%e;hv(j{QRB0zKEE`SOlVE=H0urLgKi-`#U!x9!jiNhsC zk)Q;Z;@XD`iz0yeiHeGYLP;bJgiCQCTrpAr7=q9Vf+Vhn1V~R{$X`||Ats3{Jpugz zkrY9|g(SpqO`W_a2qJJv96i7eU2x_OL?i|m76$afMS!9Z0Qxs93JEExDT(}I@s}16 z!f*saLJ>4Cc0w;maa{m|N5Bx`a8VqWlA!5dDGmgvMS?ygK(9C+ekH#ElA=JzC%j1l zy8I1|m*WqF^{mN{9*oxr%@qK*T_}5)wFDMIa^qh7C0# zq^hLEzt})XoD5_!aTj1BKnB7h;yS`O+s9dy2nwe|Q6Mc`iX#SSK~w}c{176FB5+`) zCkYM$M$ySY78Ctz0})nIlvES_)h*}>NJv-+P>e+35RqV5;L?*Wfb~d%kp~z-;6@7q z2gIc(KtLI8^a`Jp;zkQV1St*%@W3!dxB&5shyXzd3kd@$Aw+Oe5)%a`j{w301)`#V zBN<5%Wl15`UnC-ga6S#EMFjAZKmfos{Yrmzg^&Ov?6+ueu1frmA@r+TF;ACobn-9!N+SXDGr#VmOHKiF`qd!x8}XPs~ghfDnM2U+D=5 z0Y{4CCd1gQ39og=}+!@YkWX#Qo8j+?xH zPrx8Jw6k;bc69fFd$|338os4>S)GcUnH(1tX=>I!wztp3Ysd4h5`3iXM>ZC9J1EGGdRNM##~6D?ezqW_*$t~P%k4dBc+^y zWgE@E62=srJ{BU76scLd&qU&t^4(C?ArgJ$*+m9@oM>>~Gg5`M`|hK+jOV#?3*RPF z@MfHw!RNjto}oZ6_o{B+a`4f3M*URKyZU$alRF0W6c0VECf$OLw>RY0H>jn;kD9?= z1}3-7LK_fkNyraUyMNOEuSh`DLJyBo@44_J^l_0?@bV?)&T#)%jN>!iEmJPX{xxsk z;eG1K+xRlP5r%)^8S&Y?rQice`MKpW^f4vA={%ky73MLiDPCORP;_zM+kyDzBl@df zou9Uq)shppiU1)5PFlNfZ4cK-23J(j-6*@G#qi-2K0QXpsTeD8@q_f+Ycx+uEfnHF z8@1&_#HB@&6?&aKH?G$`7p*NM<&MD+!LBd4Kzml0?Fy(qi_m^DPhpx3y}814AMVYCM`?kna3A-x59rScUstgvSi5;5nyNq^~k zD;~g4;cj!T5Vn^zk*#~1Z3G_5(4X|=k2Sfox- zjH9K``D#6du$B>5!icNI~|He9hLe(j?PyFn3K(!P~l5 zDX)9jwK`9I4>d3%Wg9)X@{CB)Wi!EzU7TsvkA` zBpF<-OF21~ch}BW^F!Feuw_oHdpAobvC^T9*n2MS^xDxqGJu?1W*4lMgQlJzM5{Vz zUfYh;kIAPJRU-; zzyb{5MncKvRhsgHdEF87-U}pXIv~AXIN7;i4Ux9K@G!!POMbo3o-_FLdM-Rol&LNv zP4VV=-MrG=j+Wc?m3e8@+3)X267uI^mt3)0m06ZU1T)7Ol*EI)k|dsQT6|dhQ=93V zAQ8z?I>5j?@48@97FrL(Cq%o+r%i(I2^$>AC4BuB$&V(6P+Z7Gccg8a_IklWjdy7` z9eT%5wdO0-%G9@`r$|i|YWVA$YG-2jvR)i@F)-0)`y3Ui9mTJqvHwHTXJVtH{SC1pD5_7t% zKPLEj&A!n?C{)L+t*(D_xcEu@!z|q)+u+l-r;^GEPkT2ldcTX&RxZ}_KK-OF1+D$S zgHQjXcqlq9X#cj!(e#Ah<8xp))M8*f)rJ3JLJqpeFMA& z>eUXurP@ya`R+UUs@MoJ2#TGFDf2gfR%$#@ujGz)n;hs)HAkQ$37VB!m5e8*_3Aml zU;H%TRNp<~q9frlG2QLWP-#l5Vmf|2o$2X+&a;u!4A-z3tzoHgFk9&!ZDfUSqQg(D z{E?bp{PSH*U6VR>!hXn9N`COwm31{SI*5!}JsTIzyhGAzK=Ct-I z3Y{mu7p69;4<$Ss&3x9Kve^F-<5-x8A$lPC+Pa>*dtJY*!qL^xd@_08tkOe%ooCLu zTVV4lNA4#z$r;;YH%JN0x=me`)L6Fu?WqV~;hX6eb)uJZbC7lG%~4@|i^*50>vFX? z(V<=Neu7(E)@|pv#H`O;G~IgT7CcaDDdi)sao2;0fg7#KQ?~7wk&(e8fkS(;s8am9DodE^lqk>D9g;+Hwf5 zmvtUEYo+z0zMyy}ruu%$7_)>eTOpmdrph3WoqfM{3_QkXUR-@WOmI`A4vMA zzZUdTupu?o=y1O3d(o@PNR%6M)GD@YyykA@N{|U}ryKhqhpxzvi{h?PiRDgn=~R_J zb4IVZwW_2Iqn_OB(1hk;7yIseW5UM(uPVb7JVxq$rhY zfL&gFXdKBW`)p22O?c(F%*Tob>d|C@eF?83xO}DU=5<6Eiq2%(cA)WQRb|k-1)(vb zf$p2yg#6e~Yp>H|-^u!vhe+4Cwn&D5d?MMfQSpN{C)Dm3<1Z2Lkx?XIj8VjKQ%K}f z9GQJjp|E`qT}Jw`w|(z-@hYoJ*qaY#E{C|+R8U|}gXZ*V4~uLg2#q6eP6qRbKRd^K>-hB$$F?USdW=Tlg%^=nGo%AmFh$movn3rHoj zICYNs!ldKDJ`^{=^QD6g1}L z-uwFH%cYag5ke@;^~p^1E2Oqw_U8u`kBK>c5)wJs-nmE9@LX`VlzyHu*~s99(?DdC zrA%Ntc|I^?fm>ov{EtGK0>1>eTy`ZBq9!v}X0SxTcgIiNz4!TaXQCoH2l+hd#g%>4 zCvSNt-NNMZqA)~Mx1#u*OyzfT90nU_-R+JNw3`cfF0Hog=LzQo&&bn%h+E;m`)CKX zWV`ir)BE#zJyCr6kLIqYT>P|x$}b=F*L@zCJP2*On2;%B(!T z+ql(MP%F3)^1rNk#iq3KO8R*Fy7%6#_W@JQm6z0Hs1>s)_?LT+yt)h=iLb*ks4v9~c%&V&w>rKutWNrzjfqm~+$l34gF zYGpK9m1s2RmhbPyv4xt(MuBSO-lMNBV}k@GCCoc7;?t8Wh-d6*80Osi=p%<1NJ{y>24j;M*J#Dt?dfN*TtW*AMb^ajl4URwv@K$;=4fz zd7#xNE4jg6mq2C_Q$P-Im`0S2b*y@JVCfqT90NBrsZ z2Q7+@`0(jJ6vTCMjF18odRIP@9n8bU^ltZERbvmwSJpeq5z=~(u690)xI;w>l=iOJ zs0!F{l__(%5>ovMS7SORJvnG#6`?KkI_0`Cby@#%x~&DicP(Iu=-FzG*j72e4) z+#39K+vZAVJBHM>n7cn>L$s1~qHKvOtH?)Xh%7oDe|_|O$w@7h| zmpP4WjsFz>^HdS?1yWX49lvfIcHs|-d1S)s9h~kzP;Xvpn9jjOh0#<)FF38R-EA~k zVTpfapWB{%WtPD0M#$Hhhmy57epS$u#J}l5mtYu4Q{WZEV@@!d<`=9q>QLM>;9$K7tm_!Cy!_!1iCRWh;XKH zc`=USMLv|C&f%pGQf<9CN@`jg{B35f0h>ufnJdvn$t)^!#0ofzeB7X;@lg7t&IQj0 zs6e4wj=H;k(A+s$JSFLOg}xP}ri&n&Q+s&R*Kdjjj#l9%P_r|+JMa?%P2@klv~rH6 ze{OgYOtW3oObH7s{VWNm)3hR_Nn{8nY_p(XIb)6VgN}vM<@CiypLXtNRq$Ng5}>XA z#s++rU*bYr4{-v^qtn%|6-f<~$mv-ClYSBVO)-pc<}|J2G!!vC^cLmkiCr&5dZ6jz zElkwwmNP?ZHi1H=**h0Et(btdK_|%S?Ua~jJ!$aiZBm&`V;`y6wqDq%!Ypofi9)MA zaK+LMspQ6nyxNgK)1zOFsuw%jRY5Qq=jcJA|7a>km571?#LO2^sdjQc*`b@0qx;D8HzYiC#`siXyK^tpq5{8Hbw5Ap9xB@E# zzjdp~2WUB-(NtsZ7O%ioW(MDqIF6JM*QG*dK{fJC=9#Z8_=fkd?A9s~QGlXYSB)I~ zI=>smqS)oZZ;-f(I-~i8VZlASmqdj8$gb!35o%O|2dd?h(9c$ou+g_dN^}%pM*>Eq z<3S?hy;eNAfjZC8M`{YKah{J5G$`&mqcbQI#m3KTiedZQs|b7u_^D3yTtyjCj2x7 z@faf83{u-wZo{+pv%G0lj6O$u_K4)^x*HMzqi--ZD$i%OB_UT3h^G_CM` zF~Z{(%;O|D!i7rVwRJ-7m_Aw#z+f^NAwOX{v#l|s?V3lRD*Bpnp#9_nzr(u7^1hL@ zsaBrnPP{QT{#|bt$?!BtA!VKeEhs+zFsZD$9J^nk^8yv5{%ItFC;&cLW7~5I z-?#?(+Bz*uvx8vE)2_(#1sL?5kYUVKu6M&k(afNsS7&V}7Zylk__sYvbUYl6=srv) z(=sqRlbY^+Ue(WglpAV6iyc}G>MxUngL!1H3J)d%VBA(6#sKro_fC=$mr5&~xHfq5)-4<$*YrO#LR7N zWQ--B?p6h=j4#WbDz>SKfX-f^`N>lwOgYRZWw-V&sIZxTkuT8Ai((IZvuihy&Zu(c zVH>N4+JQ%>m9a%6W+6$XJx#Fx#uY=cA(L%Sfy%{&K1+562!)4xyU7!_f|r+-2u(RR z)gLa~DVCVe?hbGWW)Rd5)GP9ViXrS%iB~f}Qe%;88(libiJu8vYGt2n+R(8;`cDm= zeRI6m*)S-7_>@aILq%N(Pqf&>t}>}?^@{DgpD84|ggyCRk6i|^(w5IFjiv1!M2sqI zIIW9@ov5XRY;(RZ>Qp0D>%kx1SVYcr=S|iTmf5JqTndv$W zJ};d-cXh(%nlS`gJvP7j^DI-#w*=P^vp5^KPDj$O3tG>UmS;vQ%}fnzFac`KEoJX{ zb3BZko>Q40qznn;8%y11o8dPq<6ooQOk*H1Gw8(sc*jF@|DtX5-H^s)e%8+{5WYa3 z;A;~)tLo`Al>P??utVd-BCq6n!yj~(n)Z4l z5^s27kjVVyjkqh_>0o!`Mi^V?*G7s1z0~ zl=7t9x`nV_4-U%}x@f9X#;xN6&G$!1O^%xUul0ub=8laK8u43O_a>q|@;i;|vI86H zZe!9Y&xeA@-6c7?MRTlqsrejOpv-ffvnZI=SE+6}GQQ&4L>-z4xL%P~MQTBW8=~m%(WA2b9N)a&n zhTI0bwq0Fw7GCgCyA6pkX*^r_+$&X;e`3@6s45>uvv zlbf$@-K0Gw2)x+pw6xddj zcbBm5Rwm>R<+=J?fBE^xZ=XZ1RM@ZvzRo-hH`>&WD@Ycm6k+#gtIR&tY*}eh{~&I= z$oS@DwB7B&6f>>xVUnjQ$qVfG=`Vbr(p(`5HQD8kP=B0Mdh7VjC#a*O+!u@BQNfEp zE_VrWR~vZrmjw^>bw5a8spJ)C{D|1-sZGj!=J`%>#EaC|X5bz{wCwbTX@I5)~j>^gRDYyCmX^j$Sd?_D9oT75Ml?HK1RE#9+{ zWe2G{Ki{^jjs)g(*!u|-;hCMcWdxf=f!GvbN~cIZ+u%BT*`J3$+*D)G9Y&!a1*t)_ zDrJ0q_Rf8?9bI$wXW!m6H2B};OXrm!WX9prW_t3psbvq3lbS%B3Nv_=oyz^u<+8>x z$!WCs#vwd|TWeL-*Q@njm6_JQCGX*6>hPGL80tuiN5zWFYrSP)3x7I8@VUpdNvCHz z>LSd#vq9;4@nT)fc?lPpo? zJWtP4ka1dfj_3L2iAPHOtS zcrS{; z>CGxy<__opHsubf*}M=sp@^MNlCXU7l~zURrJ){vvgu)GBG=t-1#v|0xh0|%KkF1p zMsvVpIJDtMZ(dsIL1?NA49HANwUv8hf@+elk|m%V-vo}72~&DXP?}xOOj=-r@G+aQ zH7n028fHW#2kLjenS8X_Z#Z)o` zwz}AcLm=aj%9io2%x2k?1xs07v}F`H#wfUA#&(btdfp&lsRzIQ8h@#&#_f2N#|%kk zCm?oaql3YM1v;po&qY|iRAN~531gK`GRiQ)n?Aq#tyQ(qhF6-1sUz=lQ2)`-Cf)1e z&jnF|eWUb=FV#4&ly zxBIy!7oVHy-^kpzHxa#=U&u&m%h=4R9o1*>uEgddhjo;R!+0paVHLEq-~7wzZPh)8 zLS_y+ff60cdu{uXJ2sRN8HMfVoA}c7I`x%W$#oYbAo%p9AWWOeZfOb&K}=n`nQnNl z^3c*`q=17B(j^pdNeps<(;AG#sK;aB^@F}V_>DilwUhNmmF03fjzUj$Fh=ty7a1<_ zPR3bSRTDz1+YNRHYZH$6BDv?5bgLM1jur|yUc6=md+mI_RqRIPnWUz3B}i;pj$q78 zDXY|LmluJx>~p2GRNp&07*{e3wf=P%AX?{+tTT5*vz*5Vw#7>n$y%*NCv8(mcW zUHz$fqH}8$RNu!46IN^~l^^vEX?I>LFY0WLlLAzYgcChRFjNMmoSHAQTHLd?|AO-4 zk%*q#i^&Ckmn%-1yqmVRfXh0nLkf9+_gf*&f`_P|DfN+5;?t%<$JpWA$SxspWYm|o zNzq1CLe9%ZIOx_MOKM71Ktds_$rbE|i+DJ$$yGbW?pWQlWjy*YcOGYsog(Dx*0sS% zu%PFmtwf(uuG9q5f9DPcc=D+bV2KW?Yh93ZGA_VY2Q7!8Y_)aBQHK!^^T$Kv9N(=3 z)X#PKAdY)e7akUB6-(4A+Ku>)0zF*Wb>87iCq zQ}pk9FCEHTYw%6vc+a~_s1UtT7W{-QliZk4G%L7EL9I8QkIdvjw%FJ-#iB%T*UZF0 z^Yk0P!h>Oo?n^>t_Exs^2^-bs=cv9ve1Q0zLvNcX@n@G~V~D-^oc` z@YphE@4vZ!IR|MKx=`dbV%{>p<;A#>hTN4d?H;cs&$rjlZBLJHvBLK;ex!yS;)G zKl*Xed!0{kZx$*jeaa~|2}B+}kMO&M&d~Qqeg(&w)ZD@fhC!unp_MgD9uwm`J1tjU zu#-6t8*RD=@?=88CpL6qtB7qGVL4xe98S|#mx4q1yF>&kmN9%^OU6``LxzN+A?Y7) zycvir2fGb=KI_dX8<2t>_i!^=3!_q(*o;8)EXUaMj+U^g0^qe4jACvIQzFRm!cu4N ztNSLN2Ttn-hAvUd{~62D?SmBSt%*RleTzaXt)Ry#FvaB?t8btAv-Mq8UDvR>!_q0T zqi53jXi@qUQwK)w$%;u}mAw}n6+l?-@%ktxOcR?@q-atY#|;hyi&Da4%~t$1Nt4HoVan_7*&v__;I9xlqB0vyH6B zs#BRUoI0@%lmx^h4h6vyhSlworJmmC!qIu#y+4nI@!NIwOQR0TcZ;`~UjKnYVUN0tsdj)ePo2W($ zzoa-)WzuxZ(77VA#Ens8;+k{9xx$a!-YM z*0zG_iT{i1l?VR1`+9oDpCAQJO?DsAbzYxcmq6siyTV#)0-Xe!^`jt*!t5X$%9 z8C;3vYo)?B_B9-`Dmc}zOB?dwD02VnN@Up$x~Cj+j2#~&EQoO71|C+qwUipd_xR@5 z6}STk5{t{Jp_jBjGk<&>A`+zB4A!h3X<)6=PWOQx%*ZR;0~}813~wUKQ_w?^b|bW+ zaxBsDN$`OU;HcLp4(tkX^iyb3Leo6bx&hD0d2~9l z8F>q^S#i_8moCH8l2)ZPP7QFF zYM`Djzd3h}c6@pv;y#nfQIC#tGoqc2HcubjBP}=k@Cun}?Y-n{{5$BbiQ5gAyyX-O zhv>L1c1vnG%oBK5WaiLNJm0bAZyj*~jSwS_ ze|)!iNQeunOKdcaqOwfgdT7g+J$Ts1BFk2KUq=4q1#T5}7k;JeV;SY_kTkxr4=<#D zWMwT9St}pZ!Tn`UORkX2WSZwh1zC1x*Kw9!dZo&wO{y=79fZtMyO6hqp6ay3kCI9? zzuJ8oeqd#}9D*q}lx2ivv(u*7*_(|(kDZBwz5;(7$rowFoUh;Jyl^u{xi!w=;UsG# zTaeiq+H&+zn)VL}ztO2rsmPb__beVxQGH)IqjE;u{?a7Yt*P*}rKw=i@M_)nK2UGzFjuL&vm)O6%z0{>%gL3i~H)py`nS>mYHD4D20 zz4uoJuklX}P6yHsV7=rNHd`2BaTGyfFVE9F@oQiO(y(#DDis~~>9vt3VTzPpv-Eg{ z2RfNe_2;yBP4pY_f=;t^&OhUL;Wp#w{bj2z@Dz0V;35ci{Xn!w$j{nTuO=27UKlqa zNS0Sg5__~c0wIp&d;)BBZ_`5bW!0{utUD>^9kMkoE@nm{b0Ylo+coRww3;cNY;xc(=VtcNB>Fzc^ibD=j;$&9#zh_=#V zrul(8cJC)8*No`b7(v>ekt9?q0YACg%7y_-^0)YOR)5%OmxQ+Ct z1F`u=4sV_r)*Nj=+z3p9zIjd4F~I6=?`SE+Yl`b5g?BQjBKR(`TRM4@pYcgR)@_Zs zU=f5KzFf~cS=#B{$DXagsBK>&aO$ZCG0K` zBX%k~3mi?OYGg9m@YByOyGR;Et?=@X;fSef+p}o8pQBFoIr=om(c(&x-{%t&EZ| z3zr{$eobt|PnX$!#eW>)ih9-`3HwmF+oMRbj z3~hK(DRswlf=c56{e+Cnl<+frHL*&RE~B5;;D za>P&~BYte{UWfAppYpMh4`DgFM}JO#RlU!vC&gnS2yfUDc{n1+b+E0OUhqo^3IFLLkGi4#9I(!h3U@^W3c0bJ>T4;*Jblit*gdYns`8JZPRk4IkPGku1-x)@|3z>;xJqhA8nTYkGkySsyRal`+2XT_))# z3Fj*aDgqn(F?4Wc<6Xy`v*)rdk+D?G2Vsh9a5mEOPdf_Nq0Hwvdzm9wpY(0dxp;~PJ$acavd>my-p>buTA=F7o1n($XH<3ySj<|j@9oG zv^0bj?~lL7dnFm$iGxlv%@TVmBG_Uc5p*$va9!E&EOQxA$(7 zVPmxjef9M;X%KGD7gwMq-NV)sR;0K=c+_O|{pC%tUp*|HDZC-bzFtr=`??4OPs+GR z*#70cl%;;Hn*#@pWr2Ki2#R5>O6d#*H}yg>UXB{jgyNmF@&$F@JSQc{MR)u zGpkhw2G-gN2KL65e}Uqihn|!-iukF{MV#9SDX!yU)px=qaWcZdlnc8bHGeL1J=D6U zZ^Bvb+tcaI<1lw~>Sot$zvsQuA81M}K=db+s95e`6YK>JPitQh3*-o>CqgSRj%@dv zTKVrGln<9gS7jWT{aN{sr$h1vpFCLl#Hw|pBbRT~Ccb3nkoglCgfCp{DNR^fQk9Oq zMQ`PWb~?T1C0uIR4sO`a-LzD46X-MZ?FQjD9FW8gIxZ%Ch1Nd7^>ivG82QUDrEwDv zW?j24jaNoI3Jjl0Dc~1SN*ZWPxk8!Po@NSb%xd5Vf#t#VYPt%;h{-+Hs(V|~TYgFq z)igu8GI?+W@Mhsz<_bsq_Ug<|pEGE3pYY7lb8{Yb6G-2_) z@^&kKdY+`6PAJZQ)nzSnKE$b^v(m8IRtVgkFpPU1a$#<1{CL7~J4dQFiiqX?Zh4gana%Nw3Zv;(y>w*ru1X?uA|f3y9oJ)WSszvagycZ*dd#UtIop(X42BDIVbY^;*#CF4>V5i zXD3Z&bfA>7C0eI-3HdkAl#Pb2ORsw<-XOFP?^@8{CdMvkx1oa8<|VDd2yGRtM2-dJ7e z9fL}Sao(a*60J-ck@1cfluo5bQ-oSr`U7c?!6cB?YwASkAbe`CxZ}HE}8}xRuuV+Iq?C_EphG-#-*ng9{uVjjD(A+VE5K zUK0Cf+-#+bk13Y<{J4HKU^hH9C;p;Q8NPs+#p>k^O&GZ8&I`_mdoU&B{SjAp+=Rf3 zG`PMz_~cEHNWGupuCB%6yjKX+TU2a%T~Wi%I;dA|v@}a(!vP!ew*}!M@>77vTQ9%`Ynrgj^KM4H|*4man*x-|mkebHm9#l>p zANBOU&u||kVHZ5!$ehbai%5^GB;%?=oK_DsnCNXfcNSd69=L!{kB9DQ_dIPQKb<&E za_LLs>HMQv+sE&bRjfyvyXT^*n0z@r5}w7`sfMm@>%8_23`VH}-KXKUR^@4Pad<1(-=JW}KK1gBNo_eJt5F#X2e>*WZH>FCklRJL6Ur)BA~y^! zFrX!`D4DE&>n%;nP+om{D`(nRQmGXmLpjPQ6!i1udd`avc}aXwupIR*vsfrdDjN%G z;_jhtyN_$G=_XO@b5(L#!07h74{KWf>>1CGLG@w}x+h8CBI$iDP>IiaG@JZ*&Xad3 zYp`b+VsC!lW!dzkDJPG{5aBV+*+w++DYBagu_^6g&m}f5wYzn$YpD|OhdHKCoRa*+#E{BXSrIIr zz236N;8`_bs`MM#ka@;?CY&zAu)(kSP-muz!#e*ggaTs!1TUA_K*X@9E!3(lsJhgs z(TDMhGV!%@v`Vcv$rIeC@PfJnqR}e}@{zvhzC7bp_*ZFz<4jRa)xe#|QvpMq)4s(} zl@c3peT4`wcU*!KEXF0s)yaUVg8%Ws8y@|T%MxXVBILgd#IFYKQ(tZOD0B3?|BrMTa~#l+C+5m)gH{BKEJw5U<)z(nmi z4GvyYn05Zu6-<$*F*D}&S4t+kTh+|uklW<+Kvf^gqUJw_J4uFaOHi#D>64m@q=pTB zI|asm_D72ZRdRM>Jh+~d$Kzvi+%5jnM~SiWRU`@-CFC1bXU?T^F%u`!gDdoDHva9- zlq!THQOddFHA$Cn|4^k=^t!GZnU2Ks88!7Y$<(2S;RAh&c0Ffi$skx9*=s69X0a#$ zy%!hiwQ*WQn31Jz11y}Y!9^W8_n)}CvuH!*>oaAwjt4~+ zrm%vjc{<{FaLIC-Fo)cDCCnHNtmyeI%g$$Z9~W?NCvrM#Kd73Cw8g>>1ElN&xYK!Q zMXp?x{C(>UPMoDJ=;#iO-*)?WA*dS4j>BcGMw6UrBD=99oXcUU)gN(*=>?%4_@5H@ zPi5}GGko6tg}oLQd0Mx-I@hga+9AVtF4^{6xC@xccnxCU@fae*OY^b!fj4XXMsrc% zRM*krtrc)nS+FKtQK%A9oZCgqAyQp%&%8-t-VOMCaJ^N3mw4MVo$N-bBNEI0Ir)o5 z;c=-Swr`!E77oZYsOyp`AHJN`Mn|kP_L>n~jm`OT*`t?BZ>5D3*j!Xt3Cq2QqXzhA zZgkN|8deoFxqUn@x)#kE39gLg%ij~N9CCQ9^M#Xu!!d+u4)evai?T(htSx7W4qTgD zOuEcY4|vsc^w1q<$yrK6k#OLH*-?FnXNGo%TyuO);Ixw;32^~UwUopsN!p?XMWA+I z{5LKLoE}@D26u$o4mYRgKfnGe-Z*5GExN{K-b8YBg~0&Sfs_!IC+R-BpJl2b|H#ry zbEUrnGCcaq>gc?=f635!^7HtP_zvdqd6%iCtd~xJ6-6R8qf{J9})=b3Ely5@$##v9W#-X`kKSn`#~#}?1u^c1Os ze=us7C^hOd7hN`oON>NJ3SF}Y$CEWdcA!;oleXG0EU*V$zn#@r$aTcs<}>m|f624i zD!oOJJ9--2e;0MWf9Znp;EU+n)P|Xlsyntx)jvgwx%6D{ww;~L_Sf7ZUsr5Z5;Y9F zrBMYI-XCs8&Cef)TB|4r+@ zM-WW<%GtBxP8PzYrV0#9t$flh^9608*0soh{*~kW&<3D|IB=uCB(1%~1|mhZW?0p3 zrtjbIc`UESNf;P9n<>cv~XQWHjSY4l3Tp%;iI%|+Dmdl`C|cN;SVnLJl*dmO6@OAaT?THKMb=J=u+}@+yqw=H;58DjHD;{3?nd6*jGU{@vZ?=KaEeJ zZ(Ke_FH#-P+F9+@cI-=68Bb+`e98s>!w*?377}K=hX3x&r(CsRRQK12M;kM@+K;Py zpjVhWKUggU55 zO0(&79Q?7|jxO)h4%{A&QW@&rm=pvX|n8n~>|@z8?k;m{FPv|p(`A_J6opD5OQoo+uUjRL5|wYdQ2fqkvryCH`}qC$dpv%} zWAoT{KJW87=X^frbN1eOKhM#7as8|R`MX!D*2^U4A5l%OcGdlMZql_WS&|@51s?jSpqsv>h@(S zn1%SdhQ%n_SW&LV)egq?8sOVbbj=|JUa>4vZGY z%Ior2+4BBWwEU<^^Z9)YOW+la^`A89U4w5k5w25gAZx>U(euXA3$P>C$N``Sm-cKGp2k-=v%RFR^O2Q9t+%zZ#g z@(VvCy>!dg(WCj==wWyP3?^;?aRELL<lfN|h^xq( ztUjfiuydwqGE8LDJExL|CX0_a5Iq&{DT;eK90|m9;pCY8${?05lW={UbHuKd8bRGr zWSLQTGe0Hi({uCQ8}HWI3p*XK2Tfw49QcA{qiR&yFCsosi8dX{&dR-ewnx?0qtXxC zIX$(+{%B8(U8B65EnLDuoQCLXOu1X(A)@VV?_@CSXy*G@DyIC&ABv4f)|zEcKK?D4 zE?b_d(M_%9+PJxc*I*N1r2UM9xzuB4$)m+P&^KcpcuO?Q`P(tK!Ob@ZiV8G2GCA?@h5 zmyy`7yY-5NFZid(5Y4vREIAo!bDVJj%xk@KUWw^WhUDxLU>fMQZk~6EybF zHKC4V(qOvx3(})2ce|n}QK3$WUnh(9sfMJQbYnKK5L-bkr{b7IWG#DW3|gfCT<;cf^| ztF9+Q<(-MH(jz7=#+<+erKKtMW*J%H!(dWeYL05 zlBrpYE=KpG6Z*GLj7%K-l^HLr?tg7p$|1DbwxM3nt!HvQWZYO29OHj{M}dEr8BYbb zGYL5YBj# zv2q2{a3f8m(IAipIa@SNn+_mWnF=dZwtW`rsLvuaja&EyV~88$qTAk&kqe%6NLbaH zUs{SeBvYPA7*nsgqx39J!pm7yw-H1t7!Pyk6D8U`!Rg+4?ZsjkFcb0ijL7TzRoc5* zRaMt1$r)+gDxLj{n?2iQGpv7KDv|UTb?Sl6L(5?ZpM)wl=24YAA869Cm58 zDCw&>^=@$+Q^n|E$;s7h;Bs3ra;~yhPeSk7mOuZoL41X5S8}H zNCeruKsJV$N_9}s$T&Ou%mH2TEqk0#t=ZET+mhyZ96jz3pBsHkGl-L%)sxWHq}e!C z{Uo)^eE;d?fN0@g*y$^?iji1P7ZYNXoX$mSO%4r|23xVJ2h4n(p zZP{r;MLRM?a)nHdPB=+WNY(EBo*a?5Ea#EvUH-@cM7$2RJiZ}zCsQ5U6Wr&nRUxt? zH6H$6KjeU4)=gy6D$>OvF=kN$5(Bv|-jDmaGoo z7TluM%vm>0nC_**P`H2p##@INdI3%14oO@z?RSPi(|JV1{5yKraSkT0ibaL#dX^S!J^wOEFskE}{`D#++D&yF^8J z7$qPu`M@F3cuaepXT4QH%)X7iRX7#8b_Dvf&?-@3h0M+4@?U+=KD|pn$G-TO__Ez< zif#xm0G=w0bys)Zh4a*Ltwq}t8mJwksju8+&ck4PK}Wz~t5j~o;V{@e5ETb-L6GO* z|IhyeEpQK?{&`wCEw+Fjx#k)G7{MGi{IQ<7&Yubqpl;>Kata+_FzB%`0ZJh1H7p>U z7(|Gq%p;8kMUcY+D1I}bQFB0_GSD+X%mGny_q{_k3M9c$FTI&MRq#Gds zkAf(xk*FXtU~L8jQi#z6h&&0w62ZH>06`SBfyWL-*+Se}Jp>PM$z@(5zNz4XO%b8Q zK!B+N#cm6TBnBb^11N;x2r`kt<(%rG0JIShJrO%1K)zT%3IQN6L5`UZc{KR+>hqf(=H-3ln_Wk#YRMtX9UdF529_Nc=%2(ZxgCC&-#ou zKM3*12Yk*ja=96z1IRP*RtVq9(+=h3iJR3+A;j?6te^@!%`Wrug++x@h~_8=RLQjr z9ZM$cj3SZ=`0w5Z0I*$tQIQ1ly!ZLVL!jMn7I>W`sC4YyZ2w*1T;}FXQT)=0!Qo(= zM8AkoJc0Z#R5)<6qX^O9l!`=gj{=z6fbegJ&Nji^(jbazPylE#bJSYH5CjpztU?T3 zT~s7F5b$;N=Rni=)KUny%RhYpArwG#Av&85;E*my%!1VxG&7q8Vz12@<8|cn8H(#{ z7T(8^#NFT;SZ-oq5Ca|p%I6x2*cA?X5{TnrdI8RNhS5t52bT>w0D=K?0kBI&?CVEG zU@++6;v^)zL}cNeFQL%~+D2x?7W&Vl>`U_y)vJPy>K<5p>oz5dtqzb+Rx?R&ad)Z1~dfV<0pE8^wI?t@@#US ze_&?wn}FY@bBW3jN}8YO2~Nra3J?sI<{O0${+{g(!I*goYS*nQ0*vCnLo?5Bg1Jm( z2+qt;^n|N|4nb>CE#*&gCCNd}e;4Cs-{LP~#bM-@51Hs5uz#c6FtEQDL|uuQR)Yo{Ih88{9*oSTCMSO)3d|UJZdDr q9ry*z9bRUyEf|cRP!leo0D+Sd7biHxoP;d~f5*XI7N5w_tN#E^8Aa^? literal 0 HcmV?d00001 diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/zips/input_only_unverified-0.1.0.zip.sig b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/zips/input_only_unverified-0.1.0.zip.sig new file mode 100644 index 0000000000000..194bdc4e9b1c4 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/package_verification/packages/zips/input_only_unverified-0.1.0.zip.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- +Version: verified-1.0.0 +Comment: Signed with elastic-package (using GopenPGP: https://gopenpgp.org) + +wsDzBAABCgAnBQJi2nUGCZDSoYKnsOAMFBYhBOpp3B9hL6vyZ4UHQdKhgqew4AwU +AADJswv/X0nLu+yKYY8baxwLE9Y5xk5dYpXMFgOtXWxzvZ6im4Bkwy1BPiVHPS7Y +iJQKGPdy7g2UkJ4fdJXhpEIi0FDHH8i8QsOLQ8f2hfITRzw4Qi7evTQ23Y2+KXab +GmBERuvz5V6K5hux5MehMOEEwiHJw4tnn6JWDi39Z+C+FDnDILtl3cukZ5Qe9dYi +H82+eOU1Ub0bHMciD2V0Z0sjR3I3DpbZni7cdcpILxAI162VbrOuylJbJUlSIziU +UQCkH15W5cyM8nQmp2h4VeA7MIlEA+aaEpCLXfPl9vLqTqPPZxIvtT/+iMkit+Qc +NgjaAIeOElE7osl973bbd5l0JLn/5nbXVs7PvbTrS1j8nu+cqZesqpxTbpOmU8xP +2opzEYnIA+qjAp2sxPObgnRiUT6Tu1yDX8BfaE5D+BbyEQ4k+aqm+AR0joc2mdoF +RYVBt7yyAXB5kjlv0xkxqkKFqg04lgYHYN5Mt0E0mjzxw0D9/GEFSpjqqOYvIIxZ +RS9dWbzJ +=V/oa +-----END PGP SIGNATURE----- \ No newline at end of file From 10211c6df7ebe6110856fec5d199b0e3da05032d Mon Sep 17 00:00:00 2001 From: Nodir Latipov Date: Wed, 21 Sep 2022 16:29:46 +0500 Subject: [PATCH 42/55] [Unified Search] Fix regress autocomplete (#140880) * fix: refress with autocomplete * fix: autocomplite * feat: added usageCollection to unified search plugin * fix: check type * fix: jest test * refact: move usageCollection to optionalPlugins * cleanup * fix: avtocomplete in lens * fix default editro * some cleanup * feat: rename app name in Lens * feat: rename app in apm * fix: descover autocomplete --- src/plugins/discover/kibana.json | 3 +- src/plugins/discover/public/build_services.ts | 3 + src/plugins/discover/public/plugin.tsx | 2 + src/plugins/unified_search/kibana.json | 1 + src/plugins/unified_search/public/plugin.ts | 1 + .../public/query_string_input/index.tsx | 5 +- .../language_switcher.test.tsx | 14 +--- .../query_string_input/language_switcher.tsx | 9 ++- .../query_bar_menu_panels.tsx | 3 + .../query_string_input/query_bar_top_row.tsx | 31 ++++++-- .../query_string_input.test.tsx | 37 +++++---- .../query_string_input/query_string_input.tsx | 76 +++++++++++-------- src/plugins/unified_search/public/types.ts | 3 +- .../public/components/controls/filter.tsx | 30 +++++++- .../vis_default_editor/public/types.ts | 16 +++- src/plugins/vis_types/timeseries/kibana.json | 2 +- .../components/query_bar_wrapper.tsx | 30 +++++++- .../application/components/vis_editor.tsx | 3 +- .../contexts/query_input_bar_context.ts | 9 ++- .../vis_types/timeseries/public/plugin.ts | 35 ++++++++- .../vis_types/timeseries/public/services.ts | 3 + src/plugins/visualizations/kibana.json | 3 +- src/plugins/visualizations/public/mocks.ts | 2 + src/plugins/visualizations/public/plugin.ts | 4 + .../public/visualize_app/types.ts | 4 + .../utils/use/use_editor_updates.ts | 1 + .../trace_explorer/trace_search_box/index.tsx | 26 ++++++- .../context/apm_plugin/apm_plugin_context.tsx | 2 + x-pack/plugins/apm/public/plugin.ts | 2 + .../fleet/components/search_bar.tsx | 25 +++++- .../components/agent_logs/query_bar.tsx | 5 +- x-pack/plugins/fleet/public/plugin.ts | 6 +- x-pack/plugins/graph/kibana.json | 3 +- x-pack/plugins/graph/public/application.tsx | 2 + .../graph/public/apps/workspace_route.tsx | 4 +- .../graph/public/components/search_bar.tsx | 22 +++++- x-pack/plugins/graph/public/plugin.ts | 3 + .../public/pages/logs/stream/page_toolbar.tsx | 7 ++ x-pack/plugins/infra/public/types.ts | 2 + .../lens/public/app_plugin/mounter.tsx | 3 + .../plugins/lens/public/app_plugin/types.ts | 5 +- .../indexpattern_datasource/indexpattern.tsx | 3 + .../lens/public/mocks/services_mock.tsx | 5 ++ x-pack/plugins/lens/public/plugin.ts | 2 + .../query_input/query_input.tsx | 10 +++ .../contexts/kibana/kibana_context.ts | 2 + .../exploration_query_bar.tsx | 7 ++ .../explorer_query_bar/explorer_query_bar.tsx | 6 ++ .../plugins/stack_alerts/common/constants.ts | 8 ++ x-pack/plugins/stack_alerts/common/index.ts | 2 +- .../geo_containment/query_builder/index.tsx | 52 +++++++++++-- .../alerts/alert_query_bar/query_bar.tsx | 26 +++++++ .../overview/query_bar/query_bar.tsx | 25 ++++++ x-pack/plugins/synthetics/public/plugin.ts | 9 +++ x-pack/plugins/transform/kibana.json | 3 +- .../public/app/__mocks__/app_dependencies.tsx | 6 +- .../transform/public/app/app_dependencies.tsx | 4 + .../public/app/mount_management_section.ts | 3 +- .../source_search_bar/source_search_bar.tsx | 24 ++++++ x-pack/plugins/transform/public/plugin.ts | 2 + 60 files changed, 537 insertions(+), 109 deletions(-) create mode 100644 x-pack/plugins/stack_alerts/common/constants.ts diff --git a/src/plugins/discover/kibana.json b/src/plugins/discover/kibana.json index cf0bf824c6b1a..b2a42c351a102 100644 --- a/src/plugins/discover/kibana.json +++ b/src/plugins/discover/kibana.json @@ -18,7 +18,8 @@ "dataViewFieldEditor", "dataViewEditor", "expressions", - "unifiedFieldList" + "unifiedFieldList", + "unifiedSearch" ], "optionalPlugins": [ "home", diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts index 5e4140ecb6d48..86675ae54441a 100644 --- a/src/plugins/discover/public/build_services.ts +++ b/src/plugins/discover/public/build_services.ts @@ -45,6 +45,7 @@ import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; import type { SavedObjectsTaggingApi } from '@kbn/saved-objects-tagging-oss-plugin/public'; import type { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { DiscoverAppLocator } from './locator'; import { getHistory } from './kibana_services'; import { DiscoverStartPlugins } from './plugin'; @@ -88,6 +89,7 @@ export interface DiscoverServices { charts: ChartsPluginStart; savedObjectsManagement: SavedObjectsManagementPluginStart; savedObjectsTagging?: SavedObjectsTaggingApi; + unifiedSearch: UnifiedSearchPublicPluginStart; } export const buildServices = memoize(function ( @@ -136,5 +138,6 @@ export const buildServices = memoize(function ( charts: plugins.charts, savedObjectsTagging: plugins.savedObjectsTaggingOss?.getTaggingApi(), savedObjectsManagement: plugins.savedObjectsManagement, + unifiedSearch: plugins.unifiedSearch, }; }); diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index e02e6519bfda3..196fb15fb11d8 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -38,6 +38,7 @@ import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; import type { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-tagging-oss-plugin/public'; import type { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { PLUGIN_ID } from '../common'; import { DocViewInput, DocViewInputFn } from './services/doc_views/doc_views_types'; import { DocViewsRegistry } from './services/doc_views/doc_views_registry'; @@ -180,6 +181,7 @@ export interface DiscoverStartPlugins { expressions: ExpressionsStart; savedObjectsTaggingOss?: SavedObjectTaggingOssPluginStart; savedObjectsManagement: SavedObjectsManagementPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; } /** diff --git a/src/plugins/unified_search/kibana.json b/src/plugins/unified_search/kibana.json index 07e438ab52174..0dc0627ea6f4b 100755 --- a/src/plugins/unified_search/kibana.json +++ b/src/plugins/unified_search/kibana.json @@ -11,6 +11,7 @@ "ui": true, "requiredPlugins": ["dataViews", "data", "uiActions", "screenshotMode"], "requiredBundles": ["kibanaUtils", "kibanaReact", "data"], + "optionalPlugins": ["usageCollection"], "serviceFolders": ["autocomplete"], "configPath": ["unifiedSearch"] } diff --git a/src/plugins/unified_search/public/plugin.ts b/src/plugins/unified_search/public/plugin.ts index e853e6b77e8e1..645652cd60f34 100755 --- a/src/plugins/unified_search/public/plugin.ts +++ b/src/plugins/unified_search/public/plugin.ts @@ -53,6 +53,7 @@ export class UnifiedSearchPublicPlugin ); uiActions.registerAction(createUpdateFilterReferencesAction(query.filterManager)); + this.usageCollection = usageCollection; return { autocomplete: this.autocomplete.setup(core, { diff --git a/src/plugins/unified_search/public/query_string_input/index.tsx b/src/plugins/unified_search/public/query_string_input/index.tsx index 536df031edaa7..a92295b646535 100644 --- a/src/plugins/unified_search/public/query_string_input/index.tsx +++ b/src/plugins/unified_search/public/query_string_input/index.tsx @@ -7,8 +7,7 @@ */ import React from 'react'; -import { AggregateQuery, Query } from '@kbn/es-query'; -import { withKibana } from '@kbn/kibana-react-plugin/public'; +import type { AggregateQuery, Query } from '@kbn/es-query'; import type { QueryBarTopRowProps } from './query_bar_top_row'; import type { QueryStringInputProps } from './query_string_input'; @@ -24,7 +23,7 @@ export const QueryBarTopRow = ( ); -const LazyQueryStringInputUI = withKibana(React.lazy(() => import('./query_string_input'))); +const LazyQueryStringInputUI = React.lazy(() => import('./query_string_input')); export const QueryStringInput = (props: QueryStringInputProps) => ( }> diff --git a/src/plugins/unified_search/public/query_string_input/language_switcher.test.tsx b/src/plugins/unified_search/public/query_string_input/language_switcher.test.tsx index 591fe94360793..2289876fcea73 100644 --- a/src/plugins/unified_search/public/query_string_input/language_switcher.test.tsx +++ b/src/plugins/unified_search/public/query_string_input/language_switcher.test.tsx @@ -8,24 +8,14 @@ import React from 'react'; import { QueryLanguageSwitcher, QueryLanguageSwitcherProps } from './language_switcher'; -import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { coreMock } from '@kbn/core/public/mocks'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { EuiButtonIcon, EuiIcon, EuiPopover } from '@elastic/eui'; const startMock = coreMock.createStart(); describe('LanguageSwitcher', () => { - function wrapInContext(testProps: QueryLanguageSwitcherProps) { - const services = { - uiSettings: startMock.uiSettings, - docLinks: startMock.docLinks, - }; - - return ( - - - - ); + function wrapInContext(testProps: Omit) { + return ; } it('should select the lucene context menu if language is lucene', () => { diff --git a/src/plugins/unified_search/public/query_string_input/language_switcher.tsx b/src/plugins/unified_search/public/query_string_input/language_switcher.tsx index edd2028fda48c..0c369b4efc077 100644 --- a/src/plugins/unified_search/public/query_string_input/language_switcher.tsx +++ b/src/plugins/unified_search/public/query_string_input/language_switcher.tsx @@ -18,7 +18,7 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; -import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { DocLinksStart } from '@kbn/core/public'; export interface QueryLanguageSwitcherProps { language: string; @@ -27,6 +27,9 @@ export interface QueryLanguageSwitcherProps { nonKqlMode?: 'lucene' | 'text'; isOnTopBarMenu?: boolean; isDisabled?: boolean; + deps: { + docLinks: DocLinksStart; + }; } export const QueryLanguageSwitcher = React.memo(function QueryLanguageSwitcher({ @@ -36,9 +39,9 @@ export const QueryLanguageSwitcher = React.memo(function QueryLanguageSwitcher({ nonKqlMode = 'lucene', isOnTopBarMenu, isDisabled, + deps: { docLinks }, }: QueryLanguageSwitcherProps) { - const kibana = useKibana(); - const kueryQuerySyntaxDocs = kibana.services.docLinks!.links.query.kueryQuerySyntax; + const kueryQuerySyntaxDocs = docLinks.links.query.kueryQuerySyntax; const [isPopoverOpen, setIsPopoverOpen] = useState(false); const button = ( diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_menu_panels.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_menu_panels.tsx index 4a921c3a1d177..c36124ca7f448 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_menu_panels.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_menu_panels.tsx @@ -492,6 +492,9 @@ export function QueryBarMenuPanels({ onSelectLanguage={onSelectLanguage} nonKqlMode={nonKqlMode} isOnTopBarMenu={true} + deps={{ + docLinks: kibana.services.docLinks, + }} /> ), }, diff --git a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx index ca4a06d6a86f8..0780b05778ca0 100644 --- a/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_bar_top_row.tsx @@ -31,7 +31,7 @@ import { TimeHistoryContract, getQueryLog } from '@kbn/data-plugin/public'; import { i18n } from '@kbn/i18n'; import { DataView } from '@kbn/data-views-plugin/public'; import type { PersistedLog } from '@kbn/data-plugin/public'; -import { useKibana, withKibana } from '@kbn/kibana-react-plugin/public'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { UI_SETTINGS } from '@kbn/data-plugin/common'; import type { IUnifiedSearchPluginServices } from '../types'; import QueryStringInputUI from './query_string_input'; @@ -52,8 +52,6 @@ const SuperDatePicker = React.memo( EuiSuperDatePicker as any ) as unknown as typeof EuiSuperDatePicker; -const QueryStringInput = withKibana(QueryStringInputUI); - // @internal export interface QueryBarTopRowProps { customSubmitButton?: any; @@ -179,7 +177,19 @@ export const QueryBarTopRow = React.memo( const [isQueryInputFocused, setIsQueryInputFocused] = useState(false); const kibana = useKibana(); - const { uiSettings, storage, appName } = kibana.services; + + const { + uiSettings, + storage, + appName, + data, + usageCollection, + unifiedSearch, + notifications, + docLinks, + http, + } = kibana.services; + const isQueryLangSelected = props.query && !isOfQueryType(props.query); const queryLanguage = props.query && isOfQueryType(props.query) && props.query.language; @@ -511,7 +521,7 @@ export const QueryBarTopRow = React.memo( {!renderFilterMenuOnly() && renderFilterButtonGroup()} {shouldRenderQueryInput() && ( - )} diff --git a/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx b/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx index 41060aaecb3df..b0dcdac7a421c 100644 --- a/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx @@ -20,13 +20,12 @@ import { render } from '@testing-library/react'; import { EuiTextArea, EuiIcon } from '@elastic/eui'; -import { QueryLanguageSwitcher } from './language_switcher'; -import QueryStringInputUI from './query_string_input'; - import { coreMock } from '@kbn/core/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { stubIndexPattern } from '@kbn/data-plugin/public/stubs'; -import { KibanaContextProvider, withKibana } from '@kbn/kibana-react-plugin/public'; + +import { QueryLanguageSwitcher } from './language_switcher'; +import QueryStringInput from './query_string_input'; import { unifiedSearchPluginMock } from '../mocks'; jest.useFakeTimers(); @@ -63,27 +62,25 @@ const createMockStorage = () => ({ clear: jest.fn(), }); -const QueryStringInput = withKibana(QueryStringInputUI); - function wrapQueryStringInputInContext(testProps: any, storage?: any) { - const services = { - ...startMock, - unifiedSearch: unifiedSearchPluginMock.createStartContract(), - data: dataPluginMock.createStartContract(), - appName: testProps.appName || 'test', - storage: storage || createMockStorage(), - }; - const defaultOptions = { screenTitle: 'Another Screen', intl: null as any, + deps: { + unifiedSearch: unifiedSearchPluginMock.createStartContract(), + data: dataPluginMock.createStartContract(), + appName: testProps.appName || 'test', + storage: storage || createMockStorage(), + usageCollection: { reportUiCounter: () => {} }, + uiSettings: startMock.uiSettings, + http: startMock.http, + docLinks: startMock.docLinks, + }, }; return ( - - - + ); } @@ -200,7 +197,7 @@ describe('QueryStringInput', () => { }) ); - const instance = component.find('QueryStringInputUI').instance() as QueryStringInputUI; + const instance = component.find('QueryStringInputUI').instance() as QueryStringInput; const input = instance.inputRef; const inputWrapper = component.find(EuiTextArea).find('textarea'); inputWrapper.simulate('keyDown', { target: input, keyCode: 13, key: 'Enter', metaKey: true }); @@ -341,7 +338,7 @@ describe('QueryStringInput', () => { }) ); - const instance = component.find('QueryStringInputUI').instance() as QueryStringInputUI; + const instance = component.find('QueryStringInputUI').instance() as QueryStringInput; const input = instance.inputRef; const inputWrapper = component.find(EuiTextArea).find('textarea'); inputWrapper.simulate('keyDown', { target: input, keyCode: 13, key: 'Enter', metaKey: true }); @@ -379,7 +376,7 @@ describe('QueryStringInput', () => { }) ); - const instance = component.find('QueryStringInputUI').instance() as QueryStringInputUI; + const instance = component.find('QueryStringInputUI').instance() as QueryStringInput; const input = instance.inputRef; const inputWrapper = component.find(EuiTextArea).find('textarea'); input!.value = 'foo\u00A0bar'; diff --git a/src/plugins/unified_search/public/query_string_input/query_string_input.tsx b/src/plugins/unified_search/public/query_string_input/query_string_input.tsx index 84a12d8c63200..235173dc4c23c 100644 --- a/src/plugins/unified_search/public/query_string_input/query_string_input.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_string_input.tsx @@ -28,27 +28,41 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { compact, debounce, isEmpty, isEqual, isFunction } from 'lodash'; -import { Toast } from '@kbn/core/public'; +import { CoreStart, DocLinksStart, Toast } from '@kbn/core/public'; import type { Query } from '@kbn/es-query'; -import { getQueryLog } from '@kbn/data-plugin/public'; +import { DataPublicPluginStart, getQueryLog } from '@kbn/data-plugin/public'; import { DataView } from '@kbn/data-views-plugin/public'; import type { PersistedLog } from '@kbn/data-plugin/public'; import { getFieldSubtypeNested, KIBANA_USER_QUERY_LANGUAGE_KEY } from '@kbn/data-plugin/common'; -import { KibanaReactContextValue, toMountPoint } from '@kbn/kibana-react-plugin/public'; +import { toMountPoint } from '@kbn/kibana-react-plugin/public'; +import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; +import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; import { matchPairs } from './match_pairs'; import { toUser } from './to_user'; import { fromUser } from './from_user'; import { fetchIndexPatterns } from './fetch_index_patterns'; import { QueryLanguageSwitcher } from './language_switcher'; import type { SuggestionsListSize } from '../typeahead/suggestions_component'; -import type { IUnifiedSearchPluginServices } from '../types'; import { SuggestionsComponent } from '../typeahead'; import { onRaf } from '../utils'; import { FilterButtonGroup } from '../filter_bar/filter_button_group/filter_button_group'; -import { QuerySuggestion, QuerySuggestionTypes } from '../autocomplete'; +import { AutocompleteService, QuerySuggestion, QuerySuggestionTypes } from '../autocomplete'; import { getTheme } from '../services'; import './query_string_input.scss'; +export interface QueryStringInputDependencies { + unifiedSearch: { + autocomplete: ReturnType; + }; + usageCollection?: UsageCollectionStart; + data: DataPublicPluginStart; + storage: IStorageWrapper; + notifications: CoreStart['notifications']; + http: CoreStart['http']; + docLinks: DocLinksStart; + uiSettings: CoreStart['uiSettings']; +} + export interface QueryStringInputProps { indexPatterns: Array; query: Query; @@ -72,6 +86,8 @@ export interface QueryStringInputProps { isClearable?: boolean; iconType?: EuiIconProps['type']; isDisabled?: boolean; + appName: string; + deps: QueryStringInputDependencies; /** * @param nonKqlMode by default if language switch is enabled, user can switch between kql and lucene syntax mode @@ -93,10 +109,6 @@ export interface QueryStringInputProps { timeRangeForSuggestionsOverride?: boolean; } -interface Props extends QueryStringInputProps { - kibana: KibanaReactContextValue; -} - interface State { isSuggestionsVisible: boolean; index: number | null; @@ -126,7 +138,7 @@ const KEY_CODES = { // Needed for React.lazy // eslint-disable-next-line import/no-default-export -export default class QueryStringInputUI extends PureComponent { +export default class QueryStringInputUI extends PureComponent { static defaultProps = { storageKey: KIBANA_USER_QUERY_LANGUAGE_KEY, iconType: 'search', @@ -149,10 +161,10 @@ export default class QueryStringInputUI extends PureComponent { private persistedLog: PersistedLog | undefined; private abortController?: AbortController; private fetchIndexPatternsAbortController?: AbortController; - private services = this.props.kibana.services; - private reportUiCounter = this.services.usageCollection?.reportUiCounter.bind( - this.services.usageCollection, - this.services.appName + + private reportUiCounter = this.props.deps.usageCollection?.reportUiCounter.bind( + this.props.deps.usageCollection, + this.props.appName ); private componentIsUnmounting = false; @@ -181,7 +193,7 @@ export default class QueryStringInputUI extends PureComponent { const currentAbortController = this.fetchIndexPatternsAbortController; const objectPatternsFromStrings = (await fetchIndexPatterns( - this.services.data.indexPatterns, + this.props.deps.data.indexPatterns, stringPatterns )) as DataView[]; @@ -203,9 +215,9 @@ export default class QueryStringInputUI extends PureComponent { const queryString = this.getQueryString(); const recentSearchSuggestions = this.getRecentSearchSuggestions(queryString); - const hasQuerySuggestions = await this.services.unifiedSearch.autocomplete.hasQuerySuggestions( - language - ); + + const hasQuerySuggestions = + this.props.deps.unifiedSearch.autocomplete.hasQuerySuggestions(language); if ( !hasQuerySuggestions || @@ -226,7 +238,7 @@ export default class QueryStringInputUI extends PureComponent { if (this.abortController) this.abortController.abort(); this.abortController = new AbortController(); const suggestions = - (await this.services.unifiedSearch.autocomplete.getQuerySuggestions({ + (await this.props.deps.unifiedSearch.autocomplete.getQuerySuggestions({ language, indexPatterns, query: queryString, @@ -456,13 +468,13 @@ export default class QueryStringInputUI extends PureComponent { if ( subTypeNested && subTypeNested.nested && - !this.services.storage.get('kibana.KQLNestedQuerySyntaxInfoOptOut') + !this.props.deps.storage.get('kibana.KQLNestedQuerySyntaxInfoOptOut') ) { - const { notifications, docLinks } = this.services; + const { notifications, docLinks } = this.props.deps; const onKQLNestedQuerySyntaxInfoOptOut = (toast: Toast) => { - if (!this.services.storage) return; - this.services.storage.set('kibana.KQLNestedQuerySyntaxInfoOptOut', true); + if (!this.props.deps.storage) return; + this.props.deps.storage.set('kibana.KQLNestedQuerySyntaxInfoOptOut', true); notifications!.toasts.remove(toast); }; @@ -536,12 +548,12 @@ export default class QueryStringInputUI extends PureComponent { // Send telemetry info every time the user opts in or out of kuery // As a result it is important this function only ever gets called in the // UI component's change handler. - this.services.http.post('/api/kibana/kql_opt_in_stats', { + this.props.deps.http.post('/api/kibana/kql_opt_in_stats', { body: JSON.stringify({ opt_in: language === 'kuery' }), }); const storageKey = this.props.storageKey; - this.services.storage.set(storageKey!, language); + this.props.deps.storage.set(storageKey!, language); const newQuery = { query: '', language }; this.onChange(newQuery); @@ -597,10 +609,11 @@ export default class QueryStringInputUI extends PureComponent { }; private initPersistedLog = () => { - const { uiSettings, storage, appName } = this.services; + const { uiSettings } = this.props.deps; + const { appName } = this.props; this.persistedLog = this.props.persistedLog ? this.props.persistedLog - : getQueryLog(uiSettings, storage, appName, this.props.query.language); + : getQueryLog(uiSettings, this.props.deps.storage, appName, this.props.query.language); }; public onMouseEnterSuggestion = (suggestion: QuerySuggestion, index: number) => { @@ -622,7 +635,7 @@ export default class QueryStringInputUI extends PureComponent { window.addEventListener('resize', this.handleAutoHeight); } - public componentDidUpdate(prevProps: Props) { + public componentDidUpdate(prevProps: QueryStringInputProps) { const parsedQuery = fromUser(toUser(this.props.query.query)); if (!isEqual(this.props.query.query, parsedQuery)) { this.onChange({ ...this.props.query, query: parsedQuery }); @@ -721,6 +734,9 @@ export default class QueryStringInputUI extends PureComponent { anchorPosition={this.props.languageSwitcherPopoverAnchorPosition} onSelectLanguage={this.onSelectLanguage} nonKqlMode={this.props.nonKqlMode} + deps={{ + docLinks: this.props.deps.docLinks, + }} /> ); @@ -748,7 +764,7 @@ export default class QueryStringInputUI extends PureComponent { style={{ position: 'relative', width: '100%' }} aria-label={i18n.translate('unifiedSearch.query.queryBar.comboboxAriaLabel', { defaultMessage: 'Search and filter the {pageType} page', - values: { pageType: this.services.appName }, + values: { pageType: this.props.appName }, })} aria-haspopup="true" aria-expanded={this.state.isSuggestionsVisible} @@ -777,7 +793,7 @@ export default class QueryStringInputUI extends PureComponent { spellCheck={false} aria-label={i18n.translate('unifiedSearch.query.queryBar.searchInputAriaLabel', { defaultMessage: 'Start typing to search and filter the {pageType} page', - values: { pageType: this.services.appName }, + values: { pageType: this.props.appName }, })} aria-autocomplete="list" aria-controls={this.state.isSuggestionsVisible ? 'kbnTypeahead__items' : undefined} diff --git a/src/plugins/unified_search/public/types.ts b/src/plugins/unified_search/public/types.ts index 246fc87114db4..d079cd72edf81 100755 --- a/src/plugins/unified_search/public/types.ts +++ b/src/plugins/unified_search/public/types.ts @@ -13,7 +13,7 @@ import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { UsageCollectionSetup, UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; import { Query, AggregateQuery } from '@kbn/es-query'; -import { CoreStart } from '@kbn/core/public'; +import { CoreStart, DocLinksStart } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { AutocompleteSetup, AutocompleteStart } from './autocomplete'; import type { IndexPatternSelectProps, StatefulSearchBarProps } from '.'; @@ -84,6 +84,7 @@ export interface IUnifiedSearchPluginServices extends Partial { application: CoreStart['application']; http: CoreStart['http']; storage: IStorageWrapper; + docLinks: DocLinksStart; data: DataPublicPluginStart; usageCollection?: UsageCollectionStart; } diff --git a/src/plugins/vis_default_editor/public/components/controls/filter.tsx b/src/plugins/vis_default_editor/public/components/controls/filter.tsx index 95740cbaa9624..e1393e71b808d 100644 --- a/src/plugins/vis_default_editor/public/components/controls/filter.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/filter.tsx @@ -11,11 +11,12 @@ import { EuiForm, EuiButtonIcon, EuiFieldText, EuiFormRow, EuiSpacer } from '@el import { i18n } from '@kbn/i18n'; import type { Query } from '@kbn/es-query'; -import { IAggConfig, DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { IAggConfig } from '@kbn/data-plugin/public'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import type { VisDefaultEditorKibanaServices } from '../../types'; interface FilterRowProps { id: string; arrayIndex: number; @@ -41,7 +42,19 @@ function FilterRow({ onChangeValue, onRemoveFilter, }: FilterRowProps) { - const { services } = useKibana<{ data: DataPublicPluginStart; appName: string }>(); + const { services } = useKibana(); + const { + data, + unifiedSearch, + usageCollection, + storage, + notifications, + http, + docLinks, + uiSettings, + appName, + } = services; + const [showCustomLabel, setShowCustomLabel] = useState(false); const filterLabel = i18n.translate('visDefaultEditor.controls.filters.filterLabel', { defaultMessage: 'Filter {index}', @@ -53,7 +66,7 @@ function FilterRow({ const onBlur = () => { if (value.query.length > 0) { // Store filter to the query log so that it is available in autocomplete. - services.data.query.addToQueryLog(services.appName, value); + data.query.addToQueryLog(appName, value); } }; @@ -103,6 +116,17 @@ function FilterRow({ bubbleSubmitEvent={true} languageSwitcherPopoverAnchorPosition="leftDown" size="s" + deps={{ + data, + unifiedSearch, + usageCollection, + storage, + notifications, + http, + docLinks, + uiSettings, + }} + appName={appName} /> {showCustomLabel ? ( diff --git a/src/plugins/vis_default_editor/public/types.ts b/src/plugins/vis_default_editor/public/types.ts index 68375151e5068..3e3d0fbed29f1 100644 --- a/src/plugins/vis_default_editor/public/types.ts +++ b/src/plugins/vis_default_editor/public/types.ts @@ -6,8 +6,22 @@ * Side Public License, v 1. */ -import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { CoreStart, DocLinksStart } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; +import type { AutocompleteStart } from '@kbn/unified-search-plugin/public'; +import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; export interface VisDefaultEditorKibanaServices { data: DataPublicPluginStart; + appName: string; + unifiedSearch: { + autocomplete: AutocompleteStart; + }; + usageCollection?: UsageCollectionStart; + storage: IStorageWrapper; + notifications: CoreStart['notifications']; + http: CoreStart['http']; + docLinks: DocLinksStart; + uiSettings: CoreStart['uiSettings']; } diff --git a/src/plugins/vis_types/timeseries/kibana.json b/src/plugins/vis_types/timeseries/kibana.json index 9194743d3af6b..049bd6beffd6f 100644 --- a/src/plugins/vis_types/timeseries/kibana.json +++ b/src/plugins/vis_types/timeseries/kibana.json @@ -4,7 +4,7 @@ "kibanaVersion": "kibana", "server": true, "ui": true, - "requiredPlugins": ["charts", "data", "expressions", "visualizations", "inspector", "dataViews", "fieldFormats", "usageCollection"], + "requiredPlugins": ["charts", "data", "expressions", "visualizations", "inspector", "dataViews", "fieldFormats", "usageCollection", "unifiedSearch"], "optionalPlugins": ["home"], "requiredBundles": ["unifiedSearch", "kibanaUtils", "kibanaReact", "fieldFormats"], "owner": { diff --git a/src/plugins/vis_types/timeseries/public/application/components/query_bar_wrapper.tsx b/src/plugins/vis_types/timeseries/public/application/components/query_bar_wrapper.tsx index f83180dcea225..05330329105de 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/query_bar_wrapper.tsx +++ b/src/plugins/vis_types/timeseries/public/application/components/query_bar_wrapper.tsx @@ -6,14 +6,15 @@ * Side Public License, v 1. */ -import React, { useContext, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { QueryStringInput, QueryStringInputProps } from '@kbn/unified-search-plugin/public'; -import { CoreStartContext } from '../contexts/query_input_bar_context'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import type { IndexPatternValue } from '../../../common/types'; import { getDataViewsStart } from '../../services'; import { fetchIndexPattern, isStringTypeIndexPattern } from '../../../common/index_patterns_utils'; +import { TimeseriesVisDependencies } from '../../plugin'; type QueryBarWrapperProps = Pick & { indexPatterns: IndexPatternValue[]; @@ -30,7 +31,18 @@ export function QueryBarWrapper({ const dataViews = getDataViewsStart(); const [indexes, setIndexes] = useState([]); - const coreStartContext = useContext(CoreStartContext); + const kibana = useKibana(); + const { + appName, + unifiedSearch, + storage, + data, + notifications, + http, + docLinks, + uiSettings, + usageCollection, + } = kibana.services; useEffect(() => { async function fetchIndexes() { @@ -63,11 +75,21 @@ export function QueryBarWrapper({ return ( ); diff --git a/src/plugins/vis_types/timeseries/public/application/components/vis_editor.tsx b/src/plugins/vis_types/timeseries/public/application/components/vis_editor.tsx index 587c665c89041..10138f180ed28 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/vis_editor.tsx +++ b/src/plugins/vis_types/timeseries/public/application/components/vis_editor.tsx @@ -29,7 +29,7 @@ import { extractIndexPatternValues } from '../../../common/index_patterns_utils' import { TIME_RANGE_DATA_MODES, TIME_RANGE_MODE_KEY } from '../../../common/enums'; import { VisPicker } from './vis_picker'; import { fetchFields, VisFields } from '../lib/fetch_fields'; -import { getDataStart, getCoreStart } from '../../services'; +import { getDataStart, getCoreStart, getUnifiedSearchStart } from '../../services'; import type { TimeseriesVisParams } from '../../types'; import { UseIndexPatternModeCallout } from './use_index_patter_mode_callout'; @@ -189,6 +189,7 @@ export class VisEditor extends Component(null); +export const CoreStartContext = React.createContext({} as ICoreStartContext); export const CoreStartContextProvider = CoreStartContext.Provider; diff --git a/src/plugins/vis_types/timeseries/public/plugin.ts b/src/plugins/vis_types/timeseries/public/plugin.ts index 8ca5a916a7ce3..6054a0dcd3d3b 100644 --- a/src/plugins/vis_types/timeseries/public/plugin.ts +++ b/src/plugins/vis_types/timeseries/public/plugin.ts @@ -9,11 +9,17 @@ import type { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import type { Plugin as ExpressionsPublicPlugin } from '@kbn/expressions-plugin/public'; import type { VisualizationsSetup } from '@kbn/visualizations-plugin/public'; -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { DataPublicPluginStart, TimefilterContract } from '@kbn/data-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import type { ChartsPluginStart } from '@kbn/charts-plugin/public'; import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import type { IUiSettingsClient } from '@kbn/core/public'; +import type { HttpSetup } from '@kbn/core-http-browser'; +import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; +import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { EditorController, TSVB_EDITOR_NAME } from './application/editor_controller'; @@ -28,6 +34,7 @@ import { setDataViewsStart, setCharts, setUsageCollectionStart, + setUnifiedSearchStart, } from './services'; import { getTimeseriesVisRenderer } from './timeseries_vis_renderer'; @@ -44,6 +51,22 @@ export interface MetricsPluginStartDependencies { dataViews: DataViewsPublicPluginStart; charts: ChartsPluginStart; usageCollection: UsageCollectionStart; + unifiedSearch: UnifiedSearchPublicPluginStart; +} + +/** @internal */ +export interface TimeseriesVisDependencies extends Partial { + uiSettings: IUiSettingsClient; + http: HttpSetup; + timefilter: TimefilterContract; + theme: ThemeServiceStart; + appName: string; + unifiedSearch: UnifiedSearchPublicPluginStart; + notifications: CoreStart['notifications']; + storage: IStorageWrapper; + data: DataPublicPluginStart; + usageCollection?: UsageCollectionStart; + docLinks: DocLinksStart; } /** @internal */ @@ -69,12 +92,20 @@ export class MetricsPlugin implements Plugin { public start( core: CoreStart, - { data, charts, dataViews, usageCollection, fieldFormats }: MetricsPluginStartDependencies + { + data, + charts, + dataViews, + usageCollection, + fieldFormats, + unifiedSearch, + }: MetricsPluginStartDependencies ) { setCharts(charts); setI18n(core.i18n); setFieldFormats(fieldFormats); setDataStart(data); + setUnifiedSearchStart(unifiedSearch); setDataViewsStart(dataViews); setCoreStart(core); setUsageCollectionStart(usageCollection); diff --git a/src/plugins/vis_types/timeseries/public/services.ts b/src/plugins/vis_types/timeseries/public/services.ts index c68971e24822b..d7e5777361b83 100644 --- a/src/plugins/vis_types/timeseries/public/services.ts +++ b/src/plugins/vis_types/timeseries/public/services.ts @@ -13,6 +13,7 @@ import type { ChartsPluginStart } from '@kbn/charts-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); @@ -22,6 +23,8 @@ export const [getFieldFormats, setFieldFormats] = export const [getCoreStart, setCoreStart] = createGetterSetter('CoreStart'); export const [getDataStart, setDataStart] = createGetterSetter('DataStart'); +export const [getUnifiedSearchStart, setUnifiedSearchStart] = + createGetterSetter('unifiedSearchStart'); export const [getDataViewsStart, setDataViewsStart] = createGetterSetter('dataViews'); diff --git a/src/plugins/visualizations/kibana.json b/src/plugins/visualizations/kibana.json index 7a36f94061159..fc35feb51039c 100644 --- a/src/plugins/visualizations/kibana.json +++ b/src/plugins/visualizations/kibana.json @@ -17,7 +17,8 @@ "screenshotMode", "presentationUtil", "dataViews", - "dataViewEditor" + "dataViewEditor", + "unifiedSearch" ], "optionalPlugins": ["home", "share", "spaces", "savedObjectsTaggingOss"], "requiredBundles": ["kibanaUtils", "savedSearch", "kibanaReact", "charts"], diff --git a/src/plugins/visualizations/public/mocks.ts b/src/plugins/visualizations/public/mocks.ts index 49a083647fbf8..e6d0e001f4572 100644 --- a/src/plugins/visualizations/public/mocks.ts +++ b/src/plugins/visualizations/public/mocks.ts @@ -23,6 +23,7 @@ import { presentationUtilPluginMock } from '@kbn/presentation-util-plugin/public import { savedObjectTaggingOssPluginMock } from '@kbn/saved-objects-tagging-oss-plugin/public/mocks'; import { screenshotModePluginMock } from '@kbn/screenshot-mode-plugin/public/mocks'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; +import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { VisualizationsPlugin } from './plugin'; import { Schemas } from './vis_types'; import { Schema, VisualizationsSetup, VisualizationsStart } from '.'; @@ -75,6 +76,7 @@ const createInstance = async () => { urlForwarding: urlForwardingPluginMock.createStartContract(), screenshotMode: screenshotModePluginMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(), + unifiedSearch: unifiedSearchPluginMock.createStartContract(), }); return { diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index e98ba20fe3056..50245642e7fed 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -25,6 +25,8 @@ import { withNotifyOnErrors, } from '@kbn/kibana-utils-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; + import type { PluginInitializerContext, CoreSetup, @@ -135,6 +137,7 @@ export interface VisualizationsStartDeps { urlForwarding: UrlForwardingStart; screenshotMode: ScreenshotModePluginStart; fieldFormats: FieldFormatsStart; + unifiedSearch: UnifiedSearchPublicPluginStart; } /** @@ -287,6 +290,7 @@ export class VisualizationsPlugin getKibanaVersion: () => this.initializerContext.env.packageInfo.version, spaces: pluginsStart.spaces, visEditorsRegistry, + unifiedSearch: pluginsStart.unifiedSearch, }; params.element.classList.add('visAppWrapper'); diff --git a/src/plugins/visualizations/public/visualize_app/types.ts b/src/plugins/visualizations/public/visualize_app/types.ts index 88672430c2550..8fe5ad4a60775 100644 --- a/src/plugins/visualizations/public/visualize_app/types.ts +++ b/src/plugins/visualizations/public/visualize_app/types.ts @@ -10,6 +10,8 @@ import type { EventEmitter } from 'events'; import type { History } from 'history'; import type { SerializableRecord } from '@kbn/utility-types'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; + import type { CoreStart, PluginInitializerContext, @@ -110,6 +112,7 @@ export interface VisualizeServices extends CoreStart { spaces?: SpacesPluginStart; theme: ThemeServiceStart; visEditorsRegistry: VisEditorsRegistry; + unifiedSearch: UnifiedSearchPublicPluginStart; } export interface VisInstance { @@ -143,6 +146,7 @@ export interface EditorRenderProps { query?: Query; savedSearch?: SavedSearch; uiState: PersistedState; + unifiedSearch: UnifiedSearchPublicPluginStart; /** * Flag to determine if visualiztion is linked to the saved search */ diff --git a/src/plugins/visualizations/public/visualize_app/utils/use/use_editor_updates.ts b/src/plugins/visualizations/public/visualize_app/utils/use/use_editor_updates.ts index 4f7245ed436d7..1492d628d5425 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/use/use_editor_updates.ts +++ b/src/plugins/visualizations/public/visualize_app/utils/use/use_editor_updates.ts @@ -54,6 +54,7 @@ export const useEditorUpdates = ( query: queryString.getQuery() as Query, linked: !!vis.data.savedSearchId, savedSearch, + unifiedSearch: services.unifiedSearch, }); } else { embeddableHandler.updateInput({ diff --git a/x-pack/plugins/apm/public/components/app/trace_explorer/trace_search_box/index.tsx b/x-pack/plugins/apm/public/components/app/trace_explorer/trace_search_box/index.tsx index ad16bd7302220..9b62ae8e6da89 100644 --- a/x-pack/plugins/apm/public/components/app/trace_explorer/trace_search_box/index.tsx +++ b/x-pack/plugins/apm/public/components/app/trace_explorer/trace_search_box/index.tsx @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import React from 'react'; import { EuiButton, EuiFlexGroup, @@ -14,7 +15,8 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; -import React from 'react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { ApmPluginStartDeps } from '../../../../plugin'; import { TraceSearchQuery, TraceSearchType, @@ -56,7 +58,12 @@ export function TraceSearchBox({ error, loading, }: Props) { - const { unifiedSearch } = useApmPluginContext(); + const { unifiedSearch, core, data } = useApmPluginContext(); + const { notifications, http, docLinks, uiSettings } = core; + const { + services: { storage }, + } = useKibana(); + const { dataView } = useApmDataView(); return ( @@ -133,6 +140,21 @@ export function TraceSearchBox({ query: String(e.query ?? ''), }); }} + appName={i18n.translate( + 'xpack.apm.traceExplorer.appName', + { + defaultMessage: 'APM', + } + )} + deps={{ + unifiedSearch, + notifications, + http, + docLinks, + uiSettings, + data, + storage, + }} /> )} diff --git a/x-pack/plugins/apm/public/context/apm_plugin/apm_plugin_context.tsx b/x-pack/plugins/apm/public/context/apm_plugin/apm_plugin_context.tsx index a8f5ab1b149fb..dc6a035e15775 100644 --- a/x-pack/plugins/apm/public/context/apm_plugin/apm_plugin_context.tsx +++ b/x-pack/plugins/apm/public/context/apm_plugin/apm_plugin_context.tsx @@ -13,6 +13,7 @@ import { ObservabilityPublicStart } from '@kbn/observability-plugin/public'; import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { ApmPluginSetupDeps } from '../../plugin'; import { ConfigSchema } from '../..'; @@ -25,6 +26,7 @@ export interface ApmPluginContextValue { observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry; observability: ObservabilityPublicStart; dataViews: DataViewsPublicPluginStart; + data: DataPublicPluginStart; unifiedSearch: UnifiedSearchPublicPluginStart; } diff --git a/x-pack/plugins/apm/public/plugin.ts b/x-pack/plugins/apm/public/plugin.ts index 7c9050bd3804e..0ae44172f7ebb 100644 --- a/x-pack/plugins/apm/public/plugin.ts +++ b/x-pack/plugins/apm/public/plugin.ts @@ -29,6 +29,7 @@ import type { PluginSetupContract as AlertingPluginPublicSetup, PluginStartContract as AlertingPluginPublicStart, } from '@kbn/alerting-plugin/public'; +import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { FeaturesPluginSetup } from '@kbn/features-plugin/public'; import type { FleetStart } from '@kbn/fleet-plugin/public'; import type { LicensingPluginSetup } from '@kbn/licensing-plugin/public'; @@ -96,6 +97,7 @@ export interface ApmPluginStartDeps { infra?: InfraClientStartExports; dataViews: DataViewsPublicPluginStart; unifiedSearch: UnifiedSearchPublicPluginStart; + storage: IStorageWrapper; } const servicesTitle = i18n.translate('xpack.apm.navigation.servicesTitle', { diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx index fb1a1c9965780..b36e64bc901d4 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx @@ -13,6 +13,8 @@ import type { FieldSpec } from '@kbn/data-plugin/common'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; +import { i18n } from '@kbn/i18n'; + import { useStartServices } from '../hooks'; import { INDEX_NAME, AGENTS_PREFIX } from '../constants'; @@ -35,7 +37,17 @@ export const SearchBar: React.FunctionComponent = ({ indexPattern = INDEX_NAME, dataTestSubj, }) => { - const { data } = useStartServices(); + const { + data, + unifiedSearch, + storage, + notifications, + http, + docLinks, + uiSettings, + usageCollection, + } = useStartServices(); + const [indexPatternFields, setIndexPatternFields] = useState(); const isQueryValid = useMemo(() => { @@ -105,6 +117,17 @@ export const SearchBar: React.FunctionComponent = ({ submitOnBlur isClearable autoSubmit + appName={i18n.translate('xpack.fleet.appTitle', { defaultMessage: 'Fleet' })} + deps={{ + unifiedSearch, + notifications, + http, + docLinks, + uiSettings, + data, + storage, + usageCollection, + }} {...(dataTestSubj && { dataTestSubj })} /> ); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx index 0fdcc06c47e18..166387780f8cc 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx @@ -28,7 +28,8 @@ export const LogQueryBar: React.FunctionComponent<{ isQueryValid: boolean; onUpdateQuery: (query: string, runQuery?: boolean) => void; }> = memo(({ query, isQueryValid, onUpdateQuery }) => { - const { data } = useStartServices(); + const { data, notifications, http, docLinks, uiSettings, unifiedSearch, storage } = + useStartServices(); const [indexPatternFields, setIndexPatternFields] = useState(); useEffect(() => { @@ -79,6 +80,8 @@ export const LogQueryBar: React.FunctionComponent<{ onSubmit={(newQuery) => { onUpdateQuery(newQuery.query as string, true); }} + appName={i18n.translate('xpack.fleet.appTitle', { defaultMessage: 'Fleet' })} + deps={{ unifiedSearch, notifications, http, docLinks, uiSettings, data, storage }} /> ); }); diff --git a/x-pack/plugins/fleet/public/plugin.ts b/x-pack/plugins/fleet/public/plugin.ts index ad7b3b02a9aa5..5b5a31461c911 100644 --- a/x-pack/plugins/fleet/public/plugin.ts +++ b/x-pack/plugins/fleet/public/plugin.ts @@ -29,7 +29,10 @@ import { once } from 'lodash'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import type { DiscoverStart } from '@kbn/discover-plugin/public'; import type { CloudStart } from '@kbn/cloud-plugin/public'; -import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; +import type { + UsageCollectionSetup, + UsageCollectionStart, +} from '@kbn/usage-collection-plugin/public'; import { DEFAULT_APP_CATEGORIES, AppNavLinkStatus } from '@kbn/core/public'; @@ -97,6 +100,7 @@ export interface FleetStartDeps { customIntegrations: CustomIntegrationsStart; share: SharePluginStart; cloud?: CloudStart; + usageCollection?: UsageCollectionStart; } export interface FleetStartServices extends CoreStart, Exclude { diff --git a/x-pack/plugins/graph/kibana.json b/x-pack/plugins/graph/kibana.json index 3ea4d3cdca356..641e595893c0a 100644 --- a/x-pack/plugins/graph/kibana.json +++ b/x-pack/plugins/graph/kibana.json @@ -8,7 +8,8 @@ "licensing", "data", "navigation", - "savedObjects" + "savedObjects", + "unifiedSearch" ], "optionalPlugins": [ "home", diff --git a/x-pack/plugins/graph/public/application.tsx b/x-pack/plugins/graph/public/application.tsx index d3ba129dbb316..1976b12621f4f 100644 --- a/x-pack/plugins/graph/public/application.tsx +++ b/x-pack/plugins/graph/public/application.tsx @@ -22,6 +22,7 @@ import { import ReactDOM from 'react-dom'; import React from 'react'; import { DataPlugin, DataViewsContract } from '@kbn/data-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import { NavigationPublicPluginStart as NavigationStart } from '@kbn/navigation-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -56,6 +57,7 @@ export interface GraphDependencies { toastNotifications: ToastsStart; indexPatterns: DataViewsContract; data: ReturnType; + unifiedSearch: UnifiedSearchPublicPluginStart; savedObjectsClient: SavedObjectsClientContract; addBasePath: (url: string) => string; getBasePath: () => string; diff --git a/x-pack/plugins/graph/public/apps/workspace_route.tsx b/x-pack/plugins/graph/public/apps/workspace_route.tsx index 64c85bc06750d..051c0fa66ab89 100644 --- a/x-pack/plugins/graph/public/apps/workspace_route.tsx +++ b/x-pack/plugins/graph/public/apps/workspace_route.tsx @@ -37,6 +37,7 @@ export const WorkspaceRoute = ({ capabilities, storage, data, + unifiedSearch, getBasePath, addBasePath, setHeaderActionMenu, @@ -73,9 +74,10 @@ export const WorkspaceRoute = ({ appName: 'graph', storage, data, + unifiedSearch, ...coreStart, }), - [coreStart, data, storage] + [coreStart, data, storage, unifiedSearch] ); const [store] = useState(() => diff --git a/x-pack/plugins/graph/public/components/search_bar.tsx b/x-pack/plugins/graph/public/components/search_bar.tsx index 9aa05f64754cd..68b7ad7b579b1 100644 --- a/x-pack/plugins/graph/public/components/search_bar.tsx +++ b/x-pack/plugins/graph/public/components/search_bar.tsx @@ -97,7 +97,17 @@ export function SearchBarComponent(props: SearchBarStateProps & SearchBarProps) const kibana = useKibana(); const { services, overlays } = kibana; - const { savedObjects, uiSettings } = services; + const { + savedObjects, + uiSettings, + appName, + unifiedSearch, + data, + storage, + notifications, + http, + docLinks, + } = services; if (!overlays) return null; return ( @@ -161,6 +171,16 @@ export function SearchBarComponent(props: SearchBarStateProps & SearchBarProps) })} query={query} onChange={setQuery} + appName={appName} + deps={{ + unifiedSearch, + data, + storage, + notifications, + http, + docLinks, + uiSettings, + }} /> diff --git a/x-pack/plugins/graph/public/plugin.ts b/x-pack/plugins/graph/public/plugin.ts index 0d9fac79600ad..d4f8471426cc5 100644 --- a/x-pack/plugins/graph/public/plugin.ts +++ b/x-pack/plugins/graph/public/plugin.ts @@ -25,6 +25,7 @@ import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { HomePublicPluginSetup, HomePublicPluginStart } from '@kbn/home-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { SavedObjectsStart } from '@kbn/saved-objects-plugin/public'; import { checkLicense } from '../common/check_license'; import { ConfigSchema } from '../config'; @@ -37,6 +38,7 @@ export interface GraphPluginStartDependencies { navigation: NavigationStart; licensing: LicensingPluginStart; data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; savedObjects: SavedObjectsStart; home?: HomePublicPluginStart; spaces?: SpacesApi; @@ -93,6 +95,7 @@ export class GraphPlugin coreStart, navigation: pluginsStart.navigation, data: pluginsStart.data, + unifiedSearch: pluginsStart.unifiedSearch, savedObjectsClient: coreStart.savedObjects.client, addBasePath: core.http.basePath.prepend, getBasePath: core.http.basePath.get, diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx index 6076849b79f12..440edcbdd6c0e 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_toolbar.tsx @@ -12,6 +12,7 @@ import React from 'react'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import { DataView } from '@kbn/data-views-plugin/public'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { LogCustomizationMenu } from '../../../components/logging/log_customization_menu'; import { LogDatepicker } from '../../../components/logging/log_datepicker'; import { LogHighlightsMenu } from '../../../components/logging/log_highlights_menu'; @@ -31,6 +32,8 @@ export const LogsToolbar = () => { const { filterQueryDraft, isFilterQueryDraftValid, applyLogFilterQuery, setLogFilterQueryDraft } = useLogFilterStateContext(); const { setSurroundingLogsId } = useLogEntryFlyoutContext(); + const { http, notifications, docLinks, uiSettings, data, storage, unifiedSearch } = + useKibanaContextForPlugin().services; const { setHighlightTerms, @@ -71,6 +74,10 @@ export const LogsToolbar = () => { defaultMessage: 'Search for log entries… (e.g. host.name:host-1)', })} query={filterQueryDraft} + appName={i18n.translate('xpack.infra.appName', { + defaultMessage: 'Infra logs', + })} + deps={{ unifiedSearch, notifications, http, docLinks, uiSettings, data, storage }} /> diff --git a/x-pack/plugins/infra/public/types.ts b/x-pack/plugins/infra/public/types.ts index a87d7def58e60..461ed1261233a 100644 --- a/x-pack/plugins/infra/public/types.ts +++ b/x-pack/plugins/infra/public/types.ts @@ -29,6 +29,7 @@ import type { // import type { OsqueryPluginStart } from '../../osquery/public'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; +import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { UnwrapPromise } from '../common/utility_types'; import type { SourceProviderProps, @@ -75,6 +76,7 @@ export interface InfraClientStartDeps { osquery?: unknown; // OsqueryPluginStart; share: SharePluginStart; lens: LensPublicStart; + storage: IStorageWrapper; } export type InfraClientCoreSetup = CoreSetup; diff --git a/x-pack/plugins/lens/public/app_plugin/mounter.tsx b/x-pack/plugins/lens/public/app_plugin/mounter.tsx index 6aa7bef84d3e2..7cf1331282d4e 100644 --- a/x-pack/plugins/lens/public/app_plugin/mounter.tsx +++ b/x-pack/plugins/lens/public/app_plugin/mounter.tsx @@ -68,6 +68,7 @@ export async function getLensServices( fieldFormats, spaces, discover, + unifiedSearch, } = startDependencies; const storage = new Storage(localStorage); @@ -108,6 +109,8 @@ export async function getLensServices( dashboardFeatureFlag: startDependencies.dashboard.dashboardFeatureFlagConfig, spaces, discover, + unifiedSearch, + docLinks: coreStart.docLinks, }; } diff --git a/x-pack/plugins/lens/public/app_plugin/types.ts b/x-pack/plugins/lens/public/app_plugin/types.ts index 335400b4cf793..c57e580e1ad35 100644 --- a/x-pack/plugins/lens/public/app_plugin/types.ts +++ b/x-pack/plugins/lens/public/app_plugin/types.ts @@ -42,6 +42,8 @@ import type { EmbeddableEditorState, EmbeddableStateTransfer } from '@kbn/embedd import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import type { ChartsPluginSetup } from '@kbn/charts-plugin/public'; +import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import { DocLinksStart } from '@kbn/core-doc-links-browser'; import type { DatasourceMap, EditorFrameInstance, @@ -151,7 +153,8 @@ export interface LensAppServices { spaces: SpacesApi; charts: ChartsPluginSetup; discover?: DiscoverStart; - + unifiedSearch: UnifiedSearchPublicPluginStart; + docLinks: DocLinksStart; // Temporarily required until the 'by value' paradigm is default. dashboardFeatureFlag: DashboardFeatureFlagConfig; dataViewEditor: DataViewEditorStart; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 7d1ccaefd0ce1..1fcec0b6509bf 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -274,6 +274,7 @@ export function getIndexPatternDatasource({ dataViews, fieldFormats, charts, + unifiedSearch, }} > { const { inputValue, handleInputChange } = useDebouncedValue({ value, onChange }); + const lensAppServices = useKibana().services; + + const { data, uiSettings, http, notifications, docLinks, storage, unifiedSearch } = + lensAppServices; return ( ); }; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts b/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts index 941352c8f8520..e17b0d7eff412 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts @@ -41,6 +41,8 @@ interface StartPlugins { charts: ChartsPluginStart; cases?: CasesUiStart; unifiedSearch: UnifiedSearchPublicPluginStart; + core: CoreStart; + appName: string; } export type StartServices = CoreStart & StartPlugins & { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx index 79e7403cd3513..33ab5e72b9fd1 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx @@ -23,6 +23,7 @@ import { } from '../../../../../../../common/constants/search'; import { removeFilterFromQueryString } from '../../../../../explorer/explorer_utils'; import { SavedSearchQuery } from '../../../../../contexts/ml'; +import { useMlKibana } from '../../../../../contexts/kibana'; interface ErrorMessage { query: string; @@ -56,6 +57,10 @@ export const ExplorationQueryBar: FC = ({ const [idToSelectedMap, setIdToSelectedMap] = useState<{ [id: string]: boolean }>({}); const [errorMessage, setErrorMessage] = useState(undefined); + const { services } = useMlKibana(); + const { unifiedSearch, data, storage, appName, notifications, http, docLinks, uiSettings } = + services; + const searchChangeHandler = (q: Query) => setSearchInput(q); const regex = useMemo( @@ -197,6 +202,8 @@ export const ExplorationQueryBar: FC = ({ disableAutoFocus={true} dataTestSubj="mlDFAnalyticsQueryInput" languageSwitcherPopoverAnchorPosition="rightDown" + appName={appName} + deps={{ unifiedSearch, notifications, http, docLinks, uiSettings, data, storage }} /> {filters && filters.options && ( diff --git a/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx b/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx index a64625959e1b5..90afeb2efb3b1 100644 --- a/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx @@ -15,6 +15,7 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { SEARCH_QUERY_LANGUAGE, ErrorMessage } from '../../../../../common/constants/search'; import { InfluencersFilterQuery } from '../../../../../common/types/es_client'; import { useAnomalyExplorerContext } from '../../anomaly_explorer_context'; +import { useMlKibana } from '../../../contexts/kibana'; export const DEFAULT_QUERY_LANG = SEARCH_QUERY_LANGUAGE.KUERY; @@ -111,6 +112,9 @@ export const ExplorerQueryBar: FC = ({ updateLanguage, }) => { const { anomalyExplorerCommonStateService } = useAnomalyExplorerContext(); + const { services } = useMlKibana(); + const { unifiedSearch, data, storage, appName, notifications, http, docLinks, uiSettings } = + services; // The internal state of the input query bar updated on every key stroke. const [searchInput, setSearchInput] = useState( @@ -166,6 +170,8 @@ export const ExplorerQueryBar: FC = ({ disableAutoFocus dataTestSubj="explorerQueryInput" languageSwitcherPopoverAnchorPosition="rightDown" + appName={appName} + deps={{ unifiedSearch, notifications, http, docLinks, uiSettings, data, storage }} /> } isOpen={errorMessage?.query === searchInput.query && errorMessage?.message !== ''} diff --git a/x-pack/plugins/stack_alerts/common/constants.ts b/x-pack/plugins/stack_alerts/common/constants.ts new file mode 100644 index 0000000000000..cac00873face2 --- /dev/null +++ b/x-pack/plugins/stack_alerts/common/constants.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const STACK_ALERTS_FEATURE_ID = 'stackAlerts'; diff --git a/x-pack/plugins/stack_alerts/common/index.ts b/x-pack/plugins/stack_alerts/common/index.ts index 65d05a298224d..1885cbb623b1d 100644 --- a/x-pack/plugins/stack_alerts/common/index.ts +++ b/x-pack/plugins/stack_alerts/common/index.ts @@ -9,4 +9,4 @@ /* eslint-disable @kbn/eslint/no_export_all */ export * from './config'; -export const STACK_ALERTS_FEATURE_ID = 'stackAlerts'; +export { STACK_ALERTS_FEATURE_ID } from './constants'; diff --git a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx index d0739baa1ec7a..92db8171450f3 100644 --- a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx +++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx @@ -10,14 +10,22 @@ import { EuiCallOut, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { fromKueryExpression, luceneStringToDsl } from '@kbn/es-query'; -import { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public'; -import { DataView } from '@kbn/data-plugin/common'; +import type { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public'; +import type { DataView } from '@kbn/data-plugin/common'; import type { Query } from '@kbn/es-query'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; -import { GeoContainmentAlertParams } from '../types'; -import { EntityIndexExpression } from './expressions/entity_index_expression'; -import { EntityByExpression } from './expressions/entity_by_expression'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import type { HttpSetup } from '@kbn/core-http-browser'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; +import type { IUiSettingsClient } from '@kbn/core-ui-settings-server'; +import type { CoreStart } from '@kbn/core/public'; +import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; +import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; +import { STACK_ALERTS_FEATURE_ID } from '../../../../common/constants'; import { BoundaryIndexExpression } from './expressions/boundary_index_expression'; +import { EntityByExpression } from './expressions/entity_by_expression'; +import { EntityIndexExpression } from './expressions/entity_index_expression'; +import type { GeoContainmentAlertParams } from '../types'; const DEFAULT_VALUES = { TRACKING_EVENT: '', @@ -34,6 +42,15 @@ const DEFAULT_VALUES = { DELAY_OFFSET_WITH_UNITS: '0m', }; +interface KibanaDeps { + http: HttpSetup; + docLinks: DocLinksStart; + uiSettings: IUiSettingsClient; + notifications: CoreStart['notifications']; + storage: IStorageWrapper; + usageCollection: UsageCollectionStart; +} + function validateQuery(query: Query) { try { // eslint-disable-next-line @typescript-eslint/no-unused-expressions @@ -62,6 +79,9 @@ export const GeoContainmentAlertTypeExpression: React.FunctionComponent< boundaryNameField, } = ruleParams; + const { http, docLinks, uiSettings, notifications, storage, usageCollection } = + useKibana().services; + const [indexPattern, _setIndexPattern] = useState({ id: '', title: '', @@ -198,6 +218,17 @@ export const GeoContainmentAlertTypeExpression: React.FunctionComponent< setIndexQueryInput(query); } }} + appName={STACK_ALERTS_FEATURE_ID} + deps={{ + unifiedSearch, + notifications, + http, + docLinks, + uiSettings, + data, + storage, + usageCollection, + }} /> @@ -242,6 +273,17 @@ export const GeoContainmentAlertTypeExpression: React.FunctionComponent< setBoundaryIndexQueryInput(query); } }} + appName={STACK_ALERTS_FEATURE_ID} + deps={{ + unifiedSearch, + notifications, + http, + docLinks, + uiSettings, + data, + storage, + usageCollection, + }} /> diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_query_bar/query_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_query_bar/query_bar.tsx index 288cd7232a3d5..f8ed9cb99fb7c 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_query_bar/query_bar.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/alerts/alert_query_bar/query_bar.tsx @@ -9,9 +9,11 @@ import React, { useEffect, useState } from 'react'; import { EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { isValidKuery } from '../../query_bar/query_bar'; import * as labels from '../translations'; import { useUptimeDataView } from '../../../../hooks'; +import { ClientPluginsStart } from '../../../../../plugin'; interface Props { query: string; @@ -20,6 +22,19 @@ interface Props { export const AlertQueryBar = ({ query = '', onChange }: Props) => { const dataView = useUptimeDataView(); + const { services } = useKibana(); + + const { + appName, + notifications, + http, + docLinks, + uiSettings, + data, + unifiedSearch, + storage, + usageCollection, + } = services; const [inputVal, setInputVal] = useState(query); @@ -53,6 +68,17 @@ export const AlertQueryBar = ({ query = '', onChange }: Props) => { placeholder={i18n.translate('xpack.synthetics.alerts.searchPlaceholder.kql', { defaultMessage: 'Filter using kql syntax', })} + appName={appName} + deps={{ + unifiedSearch, + data, + storage, + notifications, + http, + docLinks, + uiSettings, + usageCollection, + }} /> ); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/query_bar/query_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/query_bar/query_bar.tsx index 3784bc58b76b2..5ca63c2a758e6 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/query_bar/query_bar.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/query_bar/query_bar.tsx @@ -9,9 +9,11 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFlexItem } from '@elastic/eui'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { SyntaxType, useQueryBar } from './use_query_bar'; import { KQL_PLACE_HOLDER, SIMPLE_SEARCH_PLACEHOLDER } from './translations'; import { useGetUrlParams, useUptimeDataView } from '../../../hooks'; +import { ClientPluginsStart } from '../../../../plugin'; const SYNTAX_STORAGE = 'uptime:queryBarSyntax'; @@ -32,7 +34,19 @@ export const isValidKuery = (query: string) => { export const QueryBar = () => { const { search: urlValue } = useGetUrlParams(); + const { services } = useKibana(); + const { + appName, + notifications, + http, + docLinks, + uiSettings, + data, + unifiedSearch, + storage, + usageCollection, + } = services; const { query, setQuery, submitImmediately } = useQueryBar(); const dataView = useUptimeDataView(); @@ -78,6 +92,17 @@ export const QueryBar = () => { query.language === SyntaxType.kuery ? KQL_PLACE_HOLDER : SIMPLE_SEARCH_PLACEHOLDER } isInvalid={isInValid()} + appName={appName} + deps={{ + unifiedSearch, + notifications, + http, + docLinks, + uiSettings, + data, + storage, + usageCollection, + }} /> ); diff --git a/x-pack/plugins/synthetics/public/plugin.ts b/x-pack/plugins/synthetics/public/plugin.ts index 00af06f7570e2..f795523cf0fbb 100644 --- a/x-pack/plugins/synthetics/public/plugin.ts +++ b/x-pack/plugins/synthetics/public/plugin.ts @@ -41,6 +41,8 @@ import { CasesUiStart } from '@kbn/cases-plugin/public'; import { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { SpacesPluginStart } from '@kbn/spaces-plugin/public'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; +import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; import { PLUGIN } from '../common/constants/plugin'; import { OVERVIEW_ROUTE } from '../common/constants/ui'; import { @@ -80,6 +82,13 @@ export interface ClientPluginsStart { dataViews: DataViewsPublicPluginStart; spaces: SpacesPluginStart; cloud?: CloudStart; + appName: string; + storage: IStorageWrapper; + notifications: CoreStart['notifications']; + http: CoreStart['http']; + docLinks: DocLinksStart; + uiSettings: CoreStart['uiSettings']; + usageCollection: UsageCollectionStart; } export interface UptimePluginServices extends Partial { diff --git a/x-pack/plugins/transform/kibana.json b/x-pack/plugins/transform/kibana.json index 6045d50ea26b9..dba104b3dcd2c 100644 --- a/x-pack/plugins/transform/kibana.json +++ b/x-pack/plugins/transform/kibana.json @@ -13,7 +13,8 @@ "savedObjects", "share", "triggersActionsUi", - "fieldFormats" + "fieldFormats", + "unifiedSearch" ], "optionalPlugins": [ "security", diff --git a/x-pack/plugins/transform/public/app/__mocks__/app_dependencies.tsx b/x-pack/plugins/transform/public/app/__mocks__/app_dependencies.tsx index 3a3781070a863..91fb215c814b0 100644 --- a/x-pack/plugins/transform/public/app/__mocks__/app_dependencies.tsx +++ b/x-pack/plugins/transform/public/app/__mocks__/app_dependencies.tsx @@ -14,12 +14,13 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { savedObjectsPluginMock } from '@kbn/saved-objects-plugin/public/mocks'; import { SharePluginStart } from '@kbn/share-plugin/public'; -import { Storage } from '@kbn/kibana-utils-plugin/public'; +import type { Storage } from '@kbn/kibana-utils-plugin/public'; +import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import type { AppDependencies } from '../app_dependencies'; import { MlSharedContext } from './shared_context'; import type { GetMlSharedImportsReturnType } from '../../shared_imports'; -import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; const coreSetup = coreMock.createSetup(); const coreStart = coreMock.createStart(); @@ -46,6 +47,7 @@ const appDependencies: AppDependencies = { share: { urlGenerators: { getUrlGenerator: jest.fn() } } as unknown as SharePluginStart, ml: {} as GetMlSharedImportsReturnType, triggersActionsUi: {} as jest.Mocked, + unifiedSearch: {} as jest.Mocked, }; export const useAppDependencies = () => { diff --git a/x-pack/plugins/transform/public/app/app_dependencies.tsx b/x-pack/plugins/transform/public/app/app_dependencies.tsx index 9be316b5f1d16..4c3d2ededd2c3 100644 --- a/x-pack/plugins/transform/public/app/app_dependencies.tsx +++ b/x-pack/plugins/transform/public/app/app_dependencies.tsx @@ -22,11 +22,13 @@ import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { ScopedHistory } from '@kbn/core/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; +import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; import type { GetMlSharedImportsReturnType } from '../shared_imports'; export interface AppDependencies { @@ -48,6 +50,8 @@ export interface AppDependencies { ml: GetMlSharedImportsReturnType; spaces?: SpacesPluginStart; triggersActionsUi: TriggersAndActionsUIPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; + usageCollection?: UsageCollectionStart; } export const useAppDependencies = () => { diff --git a/x-pack/plugins/transform/public/app/mount_management_section.ts b/x-pack/plugins/transform/public/app/mount_management_section.ts index 851ebf374e3e7..d5b4f07c6ff4d 100644 --- a/x-pack/plugins/transform/public/app/mount_management_section.ts +++ b/x-pack/plugins/transform/public/app/mount_management_section.ts @@ -29,7 +29,7 @@ export async function mountManagementSection( const startServices = await getStartServices(); const [core, plugins] = startServices; const { application, chrome, docLinks, i18n, overlays, theme, savedObjects, uiSettings } = core; - const { data, share, spaces, triggersActionsUi } = plugins; + const { data, share, spaces, triggersActionsUi, unifiedSearch } = plugins; const { docTitle } = chrome; // Initialize services @@ -57,6 +57,7 @@ export async function mountManagementSection( spaces, ml: await getMlSharedImports(), triggersActionsUi, + unifiedSearch, }; const unmountAppCallback = renderApp(element, appDependencies); diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx index 762f3bb72863f..dfbfced03b949 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_search_bar/source_search_bar.tsx @@ -13,9 +13,11 @@ import { i18n } from '@kbn/i18n'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; +import { PLUGIN } from '../../../../../../common/constants'; import { SearchItems } from '../../../../hooks/use_search_items'; import { StepDefineFormHook, QUERY_LANGUAGE_KUERY } from '../step_define'; +import { useAppDependencies } from '../../../../app_dependencies'; interface SourceSearchBarProps { dataView: SearchItems['dataView']; @@ -27,6 +29,17 @@ export const SourceSearchBar: FC = ({ dataView, searchBar state: { errorMessage, searchInput }, } = searchBar; + const { + uiSettings, + notifications, + http, + docLinks, + data, + storage, + unifiedSearch, + usageCollection, + } = useAppDependencies(); + return ( = ({ dataView, searchBar disableAutoFocus={true} dataTestSubj="transformQueryInput" languageSwitcherPopoverAnchorPosition="rightDown" + appName={PLUGIN.getI18nName()} + deps={{ + unifiedSearch, + notifications, + http, + docLinks, + uiSettings, + data, + storage, + usageCollection, + }} /> } isOpen={errorMessage?.query === searchInput.query && errorMessage?.message !== ''} diff --git a/x-pack/plugins/transform/public/plugin.ts b/x-pack/plugins/transform/public/plugin.ts index 762dfd2bcaab8..25f8845644f45 100644 --- a/x-pack/plugins/transform/public/plugin.ts +++ b/x-pack/plugins/transform/public/plugin.ts @@ -17,11 +17,13 @@ import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { SpacesApi } from '@kbn/spaces-plugin/public'; import type { PluginSetupContract as AlertingSetup } from '@kbn/alerting-plugin/public'; import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public'; +import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { registerFeature } from './register_feature'; import { getTransformHealthRuleType } from './alerting'; export interface PluginsDependencies { data: DataPublicPluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; dataViews: DataViewsPublicPluginStart; management: ManagementSetup; home: HomePublicPluginSetup; From 5c11b65bb663ebf57d51700daadfe70ecc5db23d Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 21 Sep 2022 13:33:28 +0200 Subject: [PATCH 43/55] [Files] Add ability to delete files on upload failure (#140716) * added server-side mocks * added upload tests * added self destruct on abort capability * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/files/common/api_routes.ts | 2 +- x-pack/plugins/files/server/mocks.ts | 29 +++++++ .../server/routes/file_kind/upload.test.ts | 84 +++++++++++++++++++ .../files/server/routes/file_kind/upload.ts | 14 +++- .../plugins/files/server/routes/test_utils.ts | 34 ++++++++ 5 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/files/server/mocks.ts create mode 100644 x-pack/plugins/files/server/routes/file_kind/upload.test.ts create mode 100644 x-pack/plugins/files/server/routes/test_utils.ts diff --git a/x-pack/plugins/files/common/api_routes.ts b/x-pack/plugins/files/common/api_routes.ts index 9eb6671465799..523fe2b2e7c8f 100644 --- a/x-pack/plugins/files/common/api_routes.ts +++ b/x-pack/plugins/files/common/api_routes.ts @@ -98,7 +98,7 @@ export type UpdateFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition< export type UploadFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition< { id: string }, - unknown, + { selfDestructOnAbort?: boolean }, { body: unknown }, { ok: true; diff --git a/x-pack/plugins/files/server/mocks.ts b/x-pack/plugins/files/server/mocks.ts new file mode 100644 index 0000000000000..c5b5afa5d842e --- /dev/null +++ b/x-pack/plugins/files/server/mocks.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { KibanaRequest } from '@kbn/core/server'; +import { DeeplyMockedKeys } from '@kbn/utility-types-jest'; +import { FileServiceFactory, FileServiceStart } from '.'; + +export const createFileServiceMock = (): DeeplyMockedKeys => ({ + create: jest.fn(), + delete: jest.fn(), + deleteShareObject: jest.fn(), + find: jest.fn(), + getById: jest.fn(), + getByToken: jest.fn(), + getShareObject: jest.fn(), + getUsageMetrics: jest.fn(), + list: jest.fn(), + listShareObjects: jest.fn(), + update: jest.fn(), + updateShareObject: jest.fn(), +}); + +export const createFileServiceFactoryMock = (): DeeplyMockedKeys => ({ + asInternal: jest.fn(createFileServiceMock), + asScoped: jest.fn((_: KibanaRequest) => createFileServiceMock()), +}); diff --git a/x-pack/plugins/files/server/routes/file_kind/upload.test.ts b/x-pack/plugins/files/server/routes/file_kind/upload.test.ts new file mode 100644 index 0000000000000..59a906f5ea988 --- /dev/null +++ b/x-pack/plugins/files/server/routes/file_kind/upload.test.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Readable } from 'stream'; +import { httpServerMock } from '@kbn/core/server/mocks'; +import { DeeplyMockedKeys } from '@kbn/utility-types-jest'; +import { kibanaResponseFactory } from '@kbn/core-http-router-server-internal'; + +import { FileServiceStart } from '../../file_service'; + +import { handler } from './upload'; +import { createFileKindsRequestHandlerContextMock } from '../test_utils'; +import { FileKindsRequestHandlerContext } from './types'; +import { File } from '../../file'; +import { AbortedUploadError } from '../../file/errors'; + +const createRequest = httpServerMock.createKibanaRequest; + +describe('upload', () => { + let ctx: FileKindsRequestHandlerContext; + let fileService: DeeplyMockedKeys; + + let uploadContent: jest.Mock>; + let deleteFn: jest.Mock>; + + const testErrorMessage = 'stop'; + const stopFn = async () => { + throw new Error(testErrorMessage); + }; + + beforeEach(async () => { + ({ ctx, fileService } = createFileKindsRequestHandlerContextMock()); + uploadContent = jest.fn(); + deleteFn = jest.fn(); + fileService.getById.mockResolvedValueOnce({ + id: 'test', + data: { size: 1 }, + uploadContent, + delete: deleteFn, + } as unknown as File); + }); + + it('errors as expected', async () => { + fileService.getById.mockReset(); + fileService.getById.mockImplementation(stopFn); + const { status, payload } = await handler( + ctx, + createRequest({ + params: { id: 'test' }, + query: { selfDestructOnFailure: true }, + body: Readable.from(['test']), + }), + kibanaResponseFactory + ); + expect(status).toBe(500); + expect(payload).toEqual({ message: testErrorMessage }); + expect(deleteFn).not.toHaveBeenCalled(); + }); + + describe('self-destruct on abort', () => { + it('deletes a file on failure to upload', async () => { + uploadContent.mockImplementationOnce(() => { + throw new AbortedUploadError('Request aborted'); + }); + + const { status, payload } = await handler( + ctx, + createRequest({ + params: { id: 'test' }, + query: { selfDestructOnAbort: true }, + body: Readable.from(['test']), + }), + kibanaResponseFactory + ); + expect(status).toBe(499); + expect(payload).toEqual({ message: 'Request aborted' }); + expect(deleteFn).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/x-pack/plugins/files/server/routes/file_kind/upload.ts b/x-pack/plugins/files/server/routes/file_kind/upload.ts index 90f09d1c15a0b..9f2e5e555dcdc 100644 --- a/x-pack/plugins/files/server/routes/file_kind/upload.ts +++ b/x-pack/plugins/files/server/routes/file_kind/upload.ts @@ -21,6 +21,11 @@ export const method = 'put' as const; export const bodySchema = schema.stream(); type Body = TypeOf; +export const querySchema = schema.object({ + selfDestructOnAbort: schema.maybe(schema.boolean()), +}); +type Query = Ensure>; + export const paramsSchema = schema.object({ id: schema.string(), }); @@ -28,7 +33,7 @@ type Params = Ensure = async ( +export const handler: FileKindsRequestHandler = async ( { files, fileKind }, req, res @@ -40,6 +45,7 @@ export const handler: FileKindsRequestHandler = async ( const sub = req.events.aborted$.subscribe(abort$); const { fileService } = await files; + const { logger } = fileService; const { body: stream, params: { id }, @@ -57,6 +63,12 @@ export const handler: FileKindsRequestHandler = async ( } else if (e instanceof fileErrors.AbortedUploadError) { fileService.usageCounter?.('UPLOAD_ERROR_ABORT'); fileService.logger.error(e); + if (req.query.selfDestructOnAbort) { + logger.info( + `File (id: ${file.id}) upload aborted. Deleting file due to self-destruct flag.` + ); + file.delete(); // fire and forget + } return res.customError({ body: { message: e.message }, statusCode: 499 }); } throw e; diff --git a/x-pack/plugins/files/server/routes/test_utils.ts b/x-pack/plugins/files/server/routes/test_utils.ts new file mode 100644 index 0000000000000..3ec4233fbcbf4 --- /dev/null +++ b/x-pack/plugins/files/server/routes/test_utils.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { createFileServiceMock } from '../mocks'; +import type { FileKindsRequestHandlerContext } from './file_kind/types'; + +export const createFileKindsRequestHandlerContextMock = ( + fileKind: string = 'test' +): { + fileService: ReturnType; + ctx: FileKindsRequestHandlerContext; +} => { + const fileService = createFileServiceMock(); + const ctx = { + fileKind, + files: Promise.resolve({ + fileService: { + asCurrentUser: () => fileService, + asInternalUser: () => fileService, + logger: loggingSystemMock.createLogger(), + }, + }), + } as unknown as FileKindsRequestHandlerContext; + + return { + ctx, + fileService, + }; +}; From 21d01719eb525d4e6e165133dca164d64af9b651 Mon Sep 17 00:00:00 2001 From: Luke Gmys Date: Wed, 21 Sep 2022 13:40:58 +0200 Subject: [PATCH 44/55] [TIP] Add inspect capability for barchart and grid requests (#140810) --- .../cypress/e2e/indicators.cy.ts | 24 +++- .../cypress/screens/indicators.ts | 8 +- .../plugins/threat_intelligence/kibana.json | 3 +- .../public/common/mocks/test_providers.tsx | 30 ++-- .../public/containers/inspector/index.tsx | 8 ++ .../public/containers/inspector/inspector.tsx | 23 ++++ .../public/hooks/use_inspector.ts | 51 +++++++ .../hooks/use_toolbar_options.test.tsx | 85 ++++++++---- .../hooks/use_toolbar_options.tsx | 36 ++++- .../hooks/use_aggregated_indicators.ts | 129 ++++++++---------- .../indicators/hooks/use_indicators.ts | 97 ++++++------- .../modules/indicators/indicators_page.tsx | 17 ++- .../indicators/lib/get_indicators_query.ts | 50 +++++++ .../indicators/lib/get_runtime_mappings.ts | 24 ++++ .../threat_intelligence/public/types.ts | 2 + 15 files changed, 403 insertions(+), 184 deletions(-) create mode 100644 x-pack/plugins/threat_intelligence/public/containers/inspector/index.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/containers/inspector/inspector.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/hooks/use_inspector.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_indicators_query.ts create mode 100644 x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_runtime_mappings.ts diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts index f9f1252f4765e..e52effa09ab3b 100644 --- a/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts @@ -28,6 +28,8 @@ import { FIELD_SELECTOR_TOGGLE_BUTTON, FIELD_SELECTOR_INPUT, FIELD_SELECTOR_LIST, + INSPECTOR_BUTTON, + INSPECTOR_PANEL, } from '../screens/indicators'; import { login } from '../tasks/login'; import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; @@ -148,11 +150,11 @@ describe('Indicators', () => { const threatFeedName = 'threat.feed.name'; cy.get(`${FIELD_SELECTOR_INPUT}`).eq(0).should('have.text', threatFeedName); - const threatIndicatorIp: string = 'threat.indicator.ip'; + const timestamp: string = '@timestamp'; cy.get(`${FIELD_SELECTOR_TOGGLE_BUTTON}`).should('exist').click(); - cy.get(`${FIELD_SELECTOR_LIST}`).should('exist').contains(threatIndicatorIp); + cy.get(`${FIELD_SELECTOR_LIST}`).should('exist').contains(timestamp); }); }); @@ -171,4 +173,22 @@ describe('Indicators', () => { }); }); }); + + describe('Request inspector', () => { + before(() => { + cy.visit(THREAT_INTELLIGENCE); + + selectRange(); + }); + + describe('when inspector button is clicked', () => { + it('should render the inspector flyout', () => { + cy.get(INSPECTOR_BUTTON).last().click({ force: true }); + + cy.get(INSPECTOR_PANEL).should('be.visible'); + + cy.get(INSPECTOR_PANEL).contains('Index patterns'); + }); + }); + }); }); diff --git a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts index b5582da6ce8ef..2bc1b704e8159 100644 --- a/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts +++ b/x-pack/plugins/threat_intelligence/cypress/screens/indicators.ts @@ -23,7 +23,7 @@ export const FLYOUT_TITLE = `[data-test-subj="tiIndicatorFlyoutTitle"]`; export const FLYOUT_TABS = `[data-test-subj="tiIndicatorFlyoutTabs"]`; -export const FLYOUT_TABLE = `[data-test-subj="tiFlyoutTableMemoryTable"]`; +export const FLYOUT_TABLE = `[data-test-subj="tiFlyoutTableTabRow"]`; export const FLYOUT_JSON = `[data-test-subj="tiFlyoutJsonCodeBlock"]`; @@ -45,7 +45,8 @@ export const FIELD_SELECTOR_INPUT = '[data-test-subj="comboBoxInput"]'; export const FIELD_SELECTOR_TOGGLE_BUTTON = '[data-test-subj="comboBoxToggleListButton"]'; -export const FIELD_SELECTOR_LIST = '[data-test-subj="comboBoxOptionsList"]'; +export const FIELD_SELECTOR_LIST = + '[data-test-subj="comboBoxOptionsList tiIndicatorFieldSelectorDropdown-optionsList"]'; export const FIELD_BROWSER = `[data-test-subj="show-field-browser"]`; @@ -113,3 +114,6 @@ export const INDICATORS_TABLE_INVESTIGATE_IN_TIMELINE_BUTTON_ICON = export const INDICATOR_FLYOUT_INVESTIGATE_IN_TIMELINE_BUTTON = '[data-test-subj="tiIndicatorFlyoutInvestigateInTimelineButton"]'; +export const INSPECTOR_BUTTON = '[data-test-subj="tiIndicatorsGridInspect"]'; + +export const INSPECTOR_PANEL = '[data-test-subj="inspectorPanel"]'; diff --git a/x-pack/plugins/threat_intelligence/kibana.json b/x-pack/plugins/threat_intelligence/kibana.json index efd1e8bce761e..f55191e68a875 100644 --- a/x-pack/plugins/threat_intelligence/kibana.json +++ b/x-pack/plugins/threat_intelligence/kibana.json @@ -16,7 +16,8 @@ "kibanaUtils", "navigation", "kibanaReact", - "triggersActionsUi" + "triggersActionsUi", + "inspector" ], "requiredBundles": [ "data", diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx index d3a94bbcce96e..7e046e214b547 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx @@ -16,6 +16,7 @@ import { Storage } from '@kbn/kibana-utils-plugin/public'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { createTGridMocks } from '@kbn/timelines-plugin/public/mock'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { RequestAdapter } from '@kbn/inspector-plugin/common'; import { KibanaContext } from '../../hooks/use_kibana'; import { SecuritySolutionPluginContext } from '../../types'; import { getSecuritySolutionContextMock } from './mock_security_context'; @@ -25,6 +26,7 @@ import { IndicatorsFiltersContext } from '../../modules/indicators/context'; import { mockIndicatorsFiltersContext } from './mock_indicators_filters_context'; import { FieldTypesContext } from '../../containers/field_types_provider'; import { generateFieldTypeMap } from './mock_field_type_map'; +import { InspectorContext } from '../../containers/inspector'; export const localStorageMock = (): IStorage => { let store: Record = {}; @@ -125,19 +127,21 @@ export const mockedServices = { }; export const TestProvidersComponent: FC = ({ children }) => ( - - - - - - - {children} - - - - - - + + + + + + + + {children} + + + + + + + ); export type MockedSearch = jest.Mocked; diff --git a/x-pack/plugins/threat_intelligence/public/containers/inspector/index.tsx b/x-pack/plugins/threat_intelligence/public/containers/inspector/index.tsx new file mode 100644 index 0000000000000..ed70296138688 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/containers/inspector/index.tsx @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './inspector'; diff --git a/x-pack/plugins/threat_intelligence/public/containers/inspector/inspector.tsx b/x-pack/plugins/threat_intelligence/public/containers/inspector/inspector.tsx new file mode 100644 index 0000000000000..622fa2df24640 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/containers/inspector/inspector.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RequestAdapter } from '@kbn/inspector-plugin/common'; +import React, { createContext, FC, useMemo } from 'react'; + +export interface InspectorContextValue { + requests: RequestAdapter; +} + +export const InspectorContext = createContext(undefined); + +export const InspectorProvider: FC = ({ children }) => { + const inspectorAdapters = useMemo(() => ({ requests: new RequestAdapter() }), []); + + return ( + {children} + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/hooks/use_inspector.ts b/x-pack/plugins/threat_intelligence/public/hooks/use_inspector.ts new file mode 100644 index 0000000000000..25aa0e5ef5da9 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/hooks/use_inspector.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useContext, useEffect, useState } from 'react'; +import { InspectorSession } from '@kbn/inspector-plugin/public'; +import { i18n } from '@kbn/i18n'; +import { useKibana } from './use_kibana'; +import { InspectorContext } from '../containers/inspector'; + +const INSPECTOR_FLYOUT_TITLE = i18n.translate('xpack.threatIntelligence.inspectorFlyoutTitle', { + defaultMessage: 'Indicators search requests', +}); + +/** + * + * @returns Exposes the adapters used to analyze requests and a method to open the inspector + */ +export const useInspector = () => { + const { + services: { inspector }, + } = useKibana(); + + const inspectorAdapters = useContext(InspectorContext); + + if (!inspectorAdapters) { + throw new Error('Inspector Context is not available'); + } + + const [inspectorSession, setInspectorSession] = useState(undefined); + + const onOpenInspector = useCallback(() => { + const session = inspector.open(inspectorAdapters, { + title: INSPECTOR_FLYOUT_TITLE, + }); + setInspectorSession(session); + }, [inspectorAdapters, inspector]); + + useEffect(() => { + return () => { + if (inspectorSession) { + inspectorSession.close(); + } + }; + }, [inspectorSession]); + + return { onOpenInspector, inspectorAdapters }; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.test.tsx index a85ca19dcea28..084279fe8353a 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.test.tsx @@ -5,21 +5,24 @@ * 2.0. */ +import { TestProvidersComponent } from '../../../../../common/mocks/test_providers'; import { renderHook } from '@testing-library/react-hooks'; import { useToolbarOptions } from './use_toolbar_options'; describe('useToolbarOptions()', () => { it('should return correct value for 0 indicators total', () => { - const result = renderHook(() => - useToolbarOptions({ - browserFields: {}, - columns: [], - end: 0, - start: 0, - indicatorCount: 0, - onResetColumns: () => {}, - onToggleColumn: () => {}, - }) + const result = renderHook( + () => + useToolbarOptions({ + browserFields: {}, + columns: [], + end: 0, + start: 0, + indicatorCount: 0, + onResetColumns: () => {}, + onToggleColumn: () => {}, + }), + { wrapper: TestProvidersComponent } ); expect(result.result.current).toMatchInlineSnapshot(` @@ -45,6 +48,12 @@ describe('useToolbarOptions()', () => { , }, + "right": , }, "showDisplaySelector": false, "showFullScreenSelector": false, @@ -53,16 +62,18 @@ describe('useToolbarOptions()', () => { }); it('should return correct value for 25 indicators total', () => { - const result = renderHook(() => - useToolbarOptions({ - browserFields: {}, - columns: [], - end: 25, - start: 0, - indicatorCount: 25, - onResetColumns: () => {}, - onToggleColumn: () => {}, - }) + const result = renderHook( + () => + useToolbarOptions({ + browserFields: {}, + columns: [], + end: 25, + start: 0, + indicatorCount: 25, + onResetColumns: () => {}, + onToggleColumn: () => {}, + }), + { wrapper: TestProvidersComponent } ); expect(result.result.current).toMatchInlineSnapshot(` @@ -95,6 +106,12 @@ describe('useToolbarOptions()', () => { , }, + "right": , }, "showDisplaySelector": false, "showFullScreenSelector": false, @@ -103,16 +120,18 @@ describe('useToolbarOptions()', () => { }); it('should return correct value for 50 indicators total', () => { - const result = renderHook(() => - useToolbarOptions({ - browserFields: {}, - columns: [], - end: 50, - start: 25, - indicatorCount: 50, - onResetColumns: () => {}, - onToggleColumn: () => {}, - }) + const result = renderHook( + () => + useToolbarOptions({ + browserFields: {}, + columns: [], + end: 50, + start: 25, + indicatorCount: 50, + onResetColumns: () => {}, + onToggleColumn: () => {}, + }), + { wrapper: TestProvidersComponent } ); expect(result.result.current).toMatchInlineSnapshot(` @@ -145,6 +164,12 @@ describe('useToolbarOptions()', () => { , }, + "right": , }, "showDisplaySelector": false, "showFullScreenSelector": false, diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.tsx index a7c4148e88aef..b19d6df71463e 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/hooks/use_toolbar_options.tsx @@ -7,10 +7,18 @@ import React from 'react'; import { useMemo } from 'react'; -import { EuiDataGridColumn, EuiText } from '@elastic/eui'; +import { EuiButtonIcon, EuiDataGridColumn, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { BrowserField } from '@kbn/rule-registry-plugin/common'; +import { useInspector } from '../../../../../hooks/use_inspector'; import { IndicatorsFieldBrowser } from '../../indicators_field_browser'; +const INSPECT_BUTTON_TEST_ID = 'tiIndicatorsGridInspect'; + +const INSPECT_BUTTON_TITLE = i18n.translate('xpack.threatIntelligence.inspectTitle', { + defaultMessage: 'Inspect', +}); + export const useToolbarOptions = ({ browserFields, start, @@ -27,8 +35,10 @@ export const useToolbarOptions = ({ columns: EuiDataGridColumn[]; onResetColumns: () => void; onToggleColumn: (columnId: string) => void; -}) => - useMemo( +}) => { + const { onOpenInspector: handleOpenInspector } = useInspector(); + + return useMemo( () => ({ showDisplaySelector: false, showFullScreenSelector: false, @@ -55,7 +65,25 @@ export const useToolbarOptions = ({ /> ), }, + right: ( + + ), }, }), - [start, end, indicatorCount, browserFields, columns, onResetColumns, onToggleColumn] + [ + indicatorCount, + end, + start, + browserFields, + columns, + onResetColumns, + onToggleColumn, + handleOpenInspector, + ] ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts index 82e59dc7b3ad3..02230defa9688 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { buildEsQuery, TimeRange } from '@kbn/es-query'; +import { TimeRange } from '@kbn/es-query'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; import { @@ -15,15 +15,16 @@ import { isErrorResponse, TimeRangeBounds, } from '@kbn/data-plugin/common'; +import { useInspector } from '../../../hooks/use_inspector'; import { useFilters } from '../../query_bar/hooks/use_filters'; import { convertAggregationToChartSeries } from '../../../common/utils/barchart'; import { RawIndicatorFieldId } from '../../../../common/types/indicator'; -import { THREAT_QUERY_BASE } from '../../../../common/constants'; import { calculateBarchartColumnTimeInterval } from '../../../common/utils/dates'; import { useKibana } from '../../../hooks/use_kibana'; import { DEFAULT_TIME_RANGE } from '../../query_bar/hooks/use_filters/utils'; import { useSourcererDataView } from './use_sourcerer_data_view'; -import { threatIndicatorNamesOriginScript, threatIndicatorNamesScript } from '../lib/display_name'; +import { getRuntimeMappings } from '../lib/get_runtime_mappings'; +import { getIndicatorsQuery } from '../lib/get_indicators_query'; export interface UseAggregatedIndicatorsParam { /** @@ -97,98 +98,73 @@ export const useAggregatedIndicators = ({ const { selectedPatterns } = useSourcererDataView(); + const { inspectorAdapters } = useInspector(); + const searchSubscription$ = useRef(new Subscription()); const abortController = useRef(new AbortController()); const [indicators, setIndicators] = useState([]); const [field, setField] = useState(DEFAULT_FIELD); + const { filters, filterQuery } = useFilters(); const dateRange: TimeRangeBounds = useMemo( () => queryService.timefilter.timefilter.calculateBounds(timeRange), [queryService, timeRange] ); - const { filters, filterQuery } = useFilters(); + const queryToExecute = useMemo(() => { + return getIndicatorsQuery({ timeRange, filters, filterQuery }); + }, [filterQuery, filters, timeRange]); const loadData = useCallback(async () => { const dateFrom: number = (dateRange.min as moment.Moment).toDate().getTime(); const dateTo: number = (dateRange.max as moment.Moment).toDate().getTime(); const interval = calculateBarchartColumnTimeInterval(dateFrom, dateTo); + const request = inspectorAdapters.requests.start('Indicator barchart', {}); + + request.stats({ + indexPattern: { + label: 'Index patterns', + value: selectedPatterns, + }, + }); + abortController.current = new AbortController(); - const queryToExecute = buildEsQuery( - undefined, - [ - { - query: THREAT_QUERY_BASE, - language: 'kuery', - }, - { - query: filterQuery.query as string, - language: 'kuery', - }, - ], - [ - ...filters, - { - query: { - range: { - [TIMESTAMP_FIELD]: { - gte: timeRange.from, - lte: timeRange.to, + const requestBody = { + aggregations: { + [AGGREGATION_NAME]: { + terms: { + field, + }, + aggs: { + events: { + date_histogram: { + field: TIMESTAMP_FIELD, + fixed_interval: interval, + min_doc_count: 0, + extended_bounds: { + min: dateFrom, + max: dateTo, + }, }, }, }, - meta: {}, }, - ] - ); + }, + fields: [TIMESTAMP_FIELD, field], + size: 0, + query: queryToExecute, + runtime_mappings: getRuntimeMappings(), + }; searchSubscription$.current = searchService .search>( { params: { index: selectedPatterns, - body: { - aggregations: { - [AGGREGATION_NAME]: { - terms: { - field, - }, - aggs: { - events: { - date_histogram: { - field: TIMESTAMP_FIELD, - fixed_interval: interval, - min_doc_count: 0, - extended_bounds: { - min: dateFrom, - max: dateTo, - }, - }, - }, - }, - }, - }, - fields: [TIMESTAMP_FIELD, field], // limit the response to only the fields we need - size: 0, // we don't need hits, just aggregations - query: queryToExecute, - runtime_mappings: { - 'threat.indicator.name': { - type: 'keyword', - script: { - source: threatIndicatorNamesScript(), - }, - }, - 'threat.indicator.name_origin': { - type: 'keyword', - script: { - source: threatIndicatorNamesOriginScript(), - }, - }, - }, - }, + body: requestBody, }, }, { @@ -202,27 +178,34 @@ export const useAggregatedIndicators = ({ response.rawResponse.aggregations[AGGREGATION_NAME]?.buckets; const chartSeries: ChartSeries[] = convertAggregationToChartSeries(aggregations); setIndicators(chartSeries); - searchSubscription$.current.unsubscribe(); + + request.stats({}).ok({ json: response }); + request.json(requestBody); } else if (isErrorResponse(response)) { + request.error({ json: response }); searchSubscription$.current.unsubscribe(); } }, - error: (msg) => { - searchService.showError(msg); + error: (requestError) => { + searchService.showError(requestError); searchSubscription$.current.unsubscribe(); + + if (requestError instanceof Error && requestError.name.includes('Abort')) { + inspectorAdapters.requests.reset(); + } else { + request.error({ json: requestError }); + } }, }); }, [ dateRange.max, dateRange.min, field, - filterQuery, - filters, + inspectorAdapters.requests, + queryToExecute, searchService, selectedPatterns, - timeRange.from, - timeRange.to, ]); const onFieldChange = useCallback( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts index 3bae1a9cecd56..e44e2e05ca230 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts @@ -13,12 +13,13 @@ import { } from '@kbn/data-plugin/common'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import type { Subscription } from 'rxjs'; -import { buildEsQuery, Filter, Query, TimeRange } from '@kbn/es-query'; +import { Filter, Query, TimeRange } from '@kbn/es-query'; +import { useInspector } from '../../../hooks/use_inspector'; import { Indicator } from '../../../../common/types/indicator'; import { useKibana } from '../../../hooks/use_kibana'; -import { THREAT_QUERY_BASE } from '../../../../common/constants'; import { useSourcererDataView } from './use_sourcerer_data_view'; -import { threatIndicatorNamesOriginScript, threatIndicatorNamesScript } from '../lib/display_name'; +import { getRuntimeMappings } from '../lib/get_runtime_mappings'; +import { getIndicatorsQuery } from '../lib/get_indicators_query'; const PAGE_SIZES = [10, 25, 50]; @@ -67,6 +68,8 @@ export const useIndicators = ({ } = useKibana(); const { selectedPatterns } = useSourcererDataView(); + const { inspectorAdapters } = useInspector(); + const searchSubscription$ = useRef(); const abortController = useRef(new AbortController()); @@ -80,36 +83,9 @@ export const useIndicators = ({ pageSizeOptions: PAGE_SIZES, }); - const queryToExecute = useMemo( - () => - buildEsQuery( - undefined, - [ - { - query: THREAT_QUERY_BASE, - language: 'kuery', - }, - { - query: filterQuery.query as string, - language: 'kuery', - }, - ], - [ - ...filters, - { - query: { - range: { - ['@timestamp']: { - gte: timeRange?.from, - lte: timeRange?.to, - }, - }, - }, - meta: {}, - }, - ] - ), - [filterQuery, filters, timeRange?.from, timeRange?.to] + const query = useMemo( + () => getIndicatorsQuery({ filters, timeRange, filterQuery }), + [filterQuery, filters, timeRange] ); const loadData = useCallback( @@ -118,32 +94,30 @@ export const useIndicators = ({ setLoading(true); + const request = inspectorAdapters.requests.start('Indicator search', {}); + + request.stats({ + indexPattern: { + label: 'Index patterns', + value: selectedPatterns, + }, + }); + + const requestBody = { + query, + runtime_mappings: getRuntimeMappings(), + fields: [{ field: '*', include_unmapped: true }], + size, + from, + sort: sorting.map(({ id, direction }) => ({ [id]: direction })), + }; + searchSubscription$.current = searchService .search>( { params: { index: selectedPatterns, - body: { - size, - from, - fields: [{ field: '*', include_unmapped: true }], - query: queryToExecute, - sort: sorting.map(({ id, direction }) => ({ [id]: direction })), - runtime_mappings: { - 'threat.indicator.name': { - type: 'keyword', - script: { - source: threatIndicatorNamesScript(), - }, - }, - 'threat.indicator.name_origin': { - type: 'keyword', - script: { - source: threatIndicatorNamesOriginScript(), - }, - }, - }, - }, + body: requestBody, }, }, { @@ -158,20 +132,29 @@ export const useIndicators = ({ if (isCompleteResponse(response)) { setLoading(false); searchSubscription$.current?.unsubscribe(); + request.stats({}).ok({ json: response }); + request.json(requestBody); } else if (isErrorResponse(response)) { setLoading(false); + request.error({ json: response }); searchSubscription$.current?.unsubscribe(); } }, - error: (msg) => { - searchService.showError(msg); + error: (requestError) => { + searchService.showError(requestError); searchSubscription$.current?.unsubscribe(); + if (requestError instanceof Error && requestError.name.includes('Abort')) { + inspectorAdapters.requests.reset(); + } else { + request.error({ json: requestError }); + } + setLoading(false); }, }); }, - [queryToExecute, searchService, selectedPatterns, sorting] + [inspectorAdapters.requests, query, searchService, selectedPatterns, sorting] ); const onChangeItemsPerPage = useCallback( diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/indicators_page.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/indicators_page.tsx index a647646861ee1..8c138ffec502b 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/indicators_page.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/indicators_page.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { VFC } from 'react'; +import React, { FC, VFC } from 'react'; import { IndicatorsFilters } from './containers/indicators_filters/indicators_filters'; import { IndicatorsBarChartWrapper } from './components/indicators_barchart_wrapper/indicators_barchart_wrapper'; import { IndicatorsTable } from './components/indicators_table/indicators_table'; @@ -16,9 +16,16 @@ import { FiltersGlobal } from '../../containers/filters_global'; import QueryBar from '../query_bar/components/query_bar'; import { useSourcererDataView } from './hooks/use_sourcerer_data_view'; import { FieldTypesProvider } from '../../containers/field_types_provider'; +import { InspectorProvider } from '../../containers/inspector'; import { useColumnSettings } from './components/indicators_table/hooks/use_column_settings'; -export const IndicatorsPage: VFC = () => { +const IndicatorsPageProviders: FC = ({ children }) => ( + + {children} + +); + +const IndicatorsPageContent: VFC = () => { const { browserFields, indexPattern } = useSourcererDataView(); const columnSettings = useColumnSettings(); @@ -75,6 +82,12 @@ export const IndicatorsPage: VFC = () => { ); }; +export const IndicatorsPage: VFC = () => ( + + + +); + // Note: This is for lazy loading // eslint-disable-next-line import/no-default-export export default IndicatorsPage; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_indicators_query.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_indicators_query.ts new file mode 100644 index 0000000000000..160fa22db7632 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_indicators_query.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildEsQuery, Filter, Query, TimeRange } from '@kbn/es-query'; +import { THREAT_QUERY_BASE } from '../../../../common/constants'; +import { RawIndicatorFieldId } from '../../../../common/types/indicator'; + +const TIMESTAMP_FIELD = RawIndicatorFieldId.TimeStamp; + +export const getIndicatorsQuery = ({ + filters, + filterQuery, + timeRange, +}: { + filters: Filter[]; + filterQuery: Query; + timeRange?: TimeRange; +}) => { + return buildEsQuery( + undefined, + [ + { + query: THREAT_QUERY_BASE, + language: 'kuery', + }, + { + query: filterQuery.query as string, + language: 'kuery', + }, + ], + [ + ...filters, + { + query: { + range: { + [TIMESTAMP_FIELD]: { + gte: timeRange?.from, + lte: timeRange?.to, + }, + }, + }, + meta: {}, + }, + ] + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_runtime_mappings.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_runtime_mappings.ts new file mode 100644 index 0000000000000..ed62b18e7c9b2 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_runtime_mappings.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { threatIndicatorNamesOriginScript, threatIndicatorNamesScript } from './display_name'; + +export const getRuntimeMappings = () => + ({ + 'threat.indicator.name': { + type: 'keyword', + script: { + source: threatIndicatorNamesScript(), + }, + }, + 'threat.indicator.name_origin': { + type: 'keyword', + script: { + source: threatIndicatorNamesOriginScript(), + }, + }, + } as const); diff --git a/x-pack/plugins/threat_intelligence/public/types.ts b/x-pack/plugins/threat_intelligence/public/types.ts index 976033934aa9a..f803231e97587 100644 --- a/x-pack/plugins/threat_intelligence/public/types.ts +++ b/x-pack/plugins/threat_intelligence/public/types.ts @@ -20,6 +20,7 @@ import { DataViewBase } from '@kbn/es-query'; import { BrowserField } from '@kbn/rule-registry-plugin/common'; import { Store } from 'redux'; import { DataProvider } from '@kbn/timelines-plugin/common'; +import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public'; export interface SecuritySolutionDataViewBase extends DataViewBase { fields: Array; @@ -45,6 +46,7 @@ export type Services = { triggersActionsUi: TriggersActionsStart; timelines: TimelinesUIStart; securityLayout: any; + inspector: InspectorPluginStart; } & CoreStart; export interface LicenseAware { From f2bb8974f70f16b64f4a2200e1691522559e025e Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 21 Sep 2022 13:47:18 +0200 Subject: [PATCH 45/55] [Files] Upload file (#140493) * wip file upload component * early version of upload component, ui only * compressed buttons * retry button and restructure some more stuff about default args for the stories * added first iteration of upload state with tests * do not self-unsubscribe * remove unused import * added simple state store observable and ability to abort uploads * rename file_upload => file_upload_ui * rename fileupload -> uploadfile and created new upload_files.ts stateful component, wip * move file kinds registry to common * hook up files registry to public side, also delete server side implementation * implemented upload file ui, changed files$ to be a list of objects, not an array of observables * did a bunch of stuff hooking up state to component * added public side mock for filesclient * rather use existing state to derive values, some other stuff * added comment * added files context * throw first error * check max file size and added abort state tets * use i18n * check mime type too and handle retry state correctly * handle immediate upload * update error message * actually give files back after done * upload files => upload file and move some stuff around * map instead of tap * use form row for showing the error message * minor refactor * export everything * move some files around * added some react jest tests too * actually add the test file (previous commit was for a fix * added processing of file names * try fix import path * remove stories for UI component * type lints * added i18n.json * reverse direction again * kibana utils bundle added * type lint * remove unnecessary variable * updated where route registration happens * remove _ * removed an option (compressed) also enabled repeated uploads and updated how the error message is laid out * put upload file component behind lazy laoding * added export of component back in * typo * do not show messages while uploading * added a test case for the display of error messages * remove unused import * expand comment * use the correct file name parser! * updated story name and how long error message is generated * rename inner render method * fix types * upload_file_ui -> upload_file.component * address a11y violation and use inline css only * updated copy per feedback * refactor state class per feedback * refactor to use context per vadims recommendation * added some more tests * added a comment and allowed passing through of kind type * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * removed props from .component since we now have context Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/.i18nrc.json | 6 +- .../file_kinds_registry/index.ts | 9 +- x-pack/plugins/files/kibana.json | 1 + .../files/public/components/context.tsx | 35 +++ .../plugins/files/public/components/index.ts | 5 +- .../upload_file/components/cancel_button.tsx | 34 +++ .../upload_file/components/clear_button.tsx | 23 ++ .../upload_file/components/control_button.tsx | 60 +++++ .../upload_file/components/index.ts | 9 + .../upload_file/components/retry_button.tsx | 33 +++ .../upload_file/components/upload_button.tsx | 36 +++ .../public/components/upload_file/context.ts | 11 + .../components/upload_file/i18n_texts.ts | 38 +++ .../public/components/upload_file/index.tsx | 20 ++ .../upload_file/upload_file.component.tsx | 114 ++++++++ .../upload_file/upload_file.stories.tsx | 141 ++++++++++ .../upload_file/upload_file.test.tsx | 203 ++++++++++++++ .../components/upload_file/upload_file.tsx | 127 +++++++++ .../upload_file/upload_state.test.ts | 175 +++++++++++++ .../components/upload_file/upload_state.ts | 247 ++++++++++++++++++ .../components/upload_file/util/index.ts | 10 + .../upload_file/util/parse_file_name.test.ts | 38 +++ .../upload_file/util/parse_file_name.ts | 24 ++ .../upload_file/util/simple_state_subject.ts | 26 ++ .../public/components/use_behavior_subject.ts | 13 + .../files/public/files_client/files_client.ts | 4 +- x-pack/plugins/files/public/index.ts | 7 + x-pack/plugins/files/public/mocks.ts | 28 ++ x-pack/plugins/files/public/plugin.ts | 47 +++- x-pack/plugins/files/public/types.ts | 6 +- x-pack/plugins/files/server/file/file.test.ts | 5 +- .../file_service/file_service_factory.ts | 2 +- .../file_service/internal_file_service.ts | 2 +- .../integration_tests/file_service.test.ts | 5 +- x-pack/plugins/files/server/plugin.ts | 19 +- .../files/server/routes/common_schemas.ts | 6 +- x-pack/plugins/files/server/routes/index.ts | 2 + .../setup_integration_environment.ts | 7 +- 38 files changed, 1528 insertions(+), 50 deletions(-) rename x-pack/plugins/files/{server => common}/file_kinds_registry/index.ts (86%) create mode 100644 x-pack/plugins/files/public/components/context.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/components/cancel_button.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/components/clear_button.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/components/control_button.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/components/index.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/components/retry_button.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/components/upload_button.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/context.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/i18n_texts.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/index.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/upload_file.component.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/upload_file.stories.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/upload_file.test.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/upload_file.tsx create mode 100644 x-pack/plugins/files/public/components/upload_file/upload_state.test.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/upload_state.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/util/index.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/util/parse_file_name.test.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/util/parse_file_name.ts create mode 100644 x-pack/plugins/files/public/components/upload_file/util/simple_state_subject.ts create mode 100644 x-pack/plugins/files/public/components/use_behavior_subject.ts create mode 100644 x-pack/plugins/files/public/mocks.ts diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 8c1b4ce3daa86..83466ba749605 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -18,6 +18,7 @@ "xpack.endpoint": "plugins/endpoint", "xpack.enterpriseSearch": "plugins/enterprise_search", "xpack.features": "plugins/features", + "xpack.files": "plugins/files", "xpack.dataVisualizer": "plugins/data_visualizer", "xpack.fileUpload": "plugins/file_upload", "xpack.globalSearch": ["plugins/global_search"], @@ -38,10 +39,7 @@ "xpack.logstash": ["plugins/logstash"], "xpack.main": "legacy/plugins/xpack_main", "xpack.maps": ["plugins/maps"], - "xpack.aiops": [ - "packages/ml/aiops_components", - "plugins/aiops" - ], + "xpack.aiops": ["packages/ml/aiops_components", "plugins/aiops"], "xpack.ml": ["plugins/ml"], "xpack.monitoring": ["plugins/monitoring"], "xpack.osquery": ["plugins/osquery"], diff --git a/x-pack/plugins/files/server/file_kinds_registry/index.ts b/x-pack/plugins/files/common/file_kinds_registry/index.ts similarity index 86% rename from x-pack/plugins/files/server/file_kinds_registry/index.ts rename to x-pack/plugins/files/common/file_kinds_registry/index.ts index bd550e43dc4b7..5df6744546c03 100644 --- a/x-pack/plugins/files/server/file_kinds_registry/index.ts +++ b/x-pack/plugins/files/common/file_kinds_registry/index.ts @@ -6,10 +6,7 @@ */ import { createGetterSetter } from '@kbn/kibana-utils-plugin/common'; import assert from 'assert'; -import { FileKind } from '../../common'; - -import { registerFileKindRoutes } from '../routes/file_kind'; -import { FilesRouter } from '../routes/types'; +import { FileKind } from '..'; export interface FileKindsRegistry { /** @@ -32,7 +29,7 @@ export interface FileKindsRegistry { * @internal */ export class FileKindsRegistryImpl implements FileKindsRegistry { - constructor(private readonly router: FilesRouter) {} + constructor(private readonly onRegister?: (fileKind: FileKind) => void) {} private readonly fileKinds = new Map(); @@ -48,7 +45,7 @@ export class FileKindsRegistryImpl implements FileKindsRegistry { } this.fileKinds.set(fileKind.id, fileKind); - registerFileKindRoutes(this.router, fileKind); + this.onRegister?.(fileKind); } get(id: string): FileKind { diff --git a/x-pack/plugins/files/kibana.json b/x-pack/plugins/files/kibana.json index d85e4403557e4..ad83b24ef0842 100755 --- a/x-pack/plugins/files/kibana.json +++ b/x-pack/plugins/files/kibana.json @@ -10,5 +10,6 @@ "server": true, "ui": true, "requiredPlugins": [], + "requiredBundles": ["kibanaUtils"], "optionalPlugins": ["security", "usageCollection"] } diff --git a/x-pack/plugins/files/public/components/context.tsx b/x-pack/plugins/files/public/components/context.tsx new file mode 100644 index 0000000000000..ceed14b52abbd --- /dev/null +++ b/x-pack/plugins/files/public/components/context.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { createContext, useContext, type FunctionComponent } from 'react'; +import { FileKindsRegistry, getFileKindsRegistry } from '../../common/file_kinds_registry'; + +export interface FilesContextValue { + registry: FileKindsRegistry; +} + +const FilesContextObject = createContext(null as unknown as FilesContextValue); + +export const useFilesContext = () => { + const ctx = useContext(FilesContextObject); + if (!ctx) { + throw new Error('FilesContext is not found!'); + } + return ctx; +}; + +export const FilesContext: FunctionComponent = ({ children }) => { + return ( + + {children} + + ); +}; diff --git a/x-pack/plugins/files/public/components/index.ts b/x-pack/plugins/files/public/components/index.ts index 9648d9e66c12f..533b37505b961 100644 --- a/x-pack/plugins/files/public/components/index.ts +++ b/x-pack/plugins/files/public/components/index.ts @@ -5,5 +5,6 @@ * 2.0. */ -export { Image } from './image'; -export type { ImageProps } from './image'; +export { Image, type ImageProps } from './image'; +export { UploadFile, type UploadFileProps } from './upload_file'; +export { FilesContext } from './context'; diff --git a/x-pack/plugins/files/public/components/upload_file/components/cancel_button.tsx b/x-pack/plugins/files/public/components/upload_file/components/cancel_button.tsx new file mode 100644 index 0000000000000..33a579ccc4c5f --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/components/cancel_button.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButtonEmpty } from '@elastic/eui'; +import type { FunctionComponent } from 'react'; +import React from 'react'; +import { useBehaviorSubject } from '../../use_behavior_subject'; +import { useUploadState } from '../context'; +import { i18nTexts } from '../i18n_texts'; + +interface Props { + onClick: () => void; +} + +export const CancelButton: FunctionComponent = ({ onClick }) => { + const uploadState = useUploadState(); + const uploading = useBehaviorSubject(uploadState.uploading$); + return ( + + {i18nTexts.cancel} + + ); +}; diff --git a/x-pack/plugins/files/public/components/upload_file/components/clear_button.tsx b/x-pack/plugins/files/public/components/upload_file/components/clear_button.tsx new file mode 100644 index 0000000000000..929fe0dcc65b0 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/components/clear_button.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButtonEmpty } from '@elastic/eui'; +import type { FunctionComponent } from 'react'; +import React from 'react'; +import { i18nTexts } from '../i18n_texts'; + +interface Props { + onClick: () => void; +} + +export const ClearButton: FunctionComponent = ({ onClick }) => { + return ( + + {i18nTexts.clear} + + ); +}; diff --git a/x-pack/plugins/files/public/components/upload_file/components/control_button.tsx b/x-pack/plugins/files/public/components/upload_file/components/control_button.tsx new file mode 100644 index 0000000000000..6898adc9cce36 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/components/control_button.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup, EuiIcon, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; +import type { FunctionComponent } from 'react'; +import React from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { useBehaviorSubject } from '../../use_behavior_subject'; +import { useUploadState } from '../context'; +import { i18nTexts } from '../i18n_texts'; +import { UploadButton } from './upload_button'; +import { RetryButton } from './retry_button'; +import { CancelButton } from './cancel_button'; + +const { euiButtonHeightSmall } = euiThemeVars; + +interface Props { + onCancel: () => void; + onUpload: () => void; + immediate?: boolean; +} + +export const ControlButton: FunctionComponent = ({ onCancel, onUpload, immediate }) => { + const uploadState = useUploadState(); + const { + euiTheme: { size }, + } = useEuiTheme(); + const uploading = useBehaviorSubject(uploadState.uploading$); + const files = useObservable(uploadState.files$, []); + const done = useObservable(uploadState.done$); + const retry = Boolean(files.some((f) => f.status === 'upload_failed')); + + if (uploading) return ; + if (retry) return ; + if (!done && !immediate) return ; + + if (done) { + return ( + + + + ); + } + return null; +}; diff --git a/x-pack/plugins/files/public/components/upload_file/components/index.ts b/x-pack/plugins/files/public/components/upload_file/components/index.ts new file mode 100644 index 0000000000000..fbc7ffd8eda79 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/components/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { ControlButton } from './control_button'; +export { ClearButton } from './clear_button'; diff --git a/x-pack/plugins/files/public/components/upload_file/components/retry_button.tsx b/x-pack/plugins/files/public/components/upload_file/components/retry_button.tsx new file mode 100644 index 0000000000000..55df91c5be3e8 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/components/retry_button.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiButtonEmpty } from '@elastic/eui'; +import type { FunctionComponent } from 'react'; +import React from 'react'; +import { useBehaviorSubject } from '../../use_behavior_subject'; +import { useUploadState } from '../context'; +import { i18nTexts } from '../i18n_texts'; + +interface Props { + onClick: () => void; +} + +export const RetryButton: FunctionComponent = ({ onClick }) => { + const uploadState = useUploadState(); + const uploading = useBehaviorSubject(uploadState.uploading$); + + return ( + + {i18nTexts.retry} + + ); +}; diff --git a/x-pack/plugins/files/public/components/upload_file/components/upload_button.tsx b/x-pack/plugins/files/public/components/upload_file/components/upload_button.tsx new file mode 100644 index 0000000000000..c9918874f7895 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/components/upload_button.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButton } from '@elastic/eui'; +import type { FunctionComponent } from 'react'; +import React from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { i18nTexts } from '../i18n_texts'; +import { useUploadState } from '../context'; +import { useBehaviorSubject } from '../../use_behavior_subject'; + +interface Props { + onClick: () => void; +} + +export const UploadButton: FunctionComponent = ({ onClick }) => { + const uploadState = useUploadState(); + const uploading = useBehaviorSubject(uploadState.uploading$); + const error = useBehaviorSubject(uploadState.error$); + const files = useObservable(uploadState.files$, []); + return ( + + {uploading ? i18nTexts.uploading : i18nTexts.upload} + + ); +}; diff --git a/x-pack/plugins/files/public/components/upload_file/context.ts b/x-pack/plugins/files/public/components/upload_file/context.ts new file mode 100644 index 0000000000000..e88f5d2441489 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/context.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import type { UploadState } from './upload_state'; + +export const context = React.createContext(null); +export const useUploadState = () => React.useContext(context)!; diff --git a/x-pack/plugins/files/public/components/upload_file/i18n_texts.ts b/x-pack/plugins/files/public/components/upload_file/i18n_texts.ts new file mode 100644 index 0000000000000..2077d635d3050 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/i18n_texts.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 { i18n } from '@kbn/i18n'; + +export const i18nTexts = { + defaultPickerLabel: i18n.translate('xpack.files.uploadFile.defaultFilePickerLabel', { + defaultMessage: 'Upload a file', + }), + upload: i18n.translate('xpack.files.uploadFile.uploadButtonLabel', { + defaultMessage: 'Upload', + }), + uploading: i18n.translate('xpack.files.uploadFile.uploadingButtonLabel', { + defaultMessage: 'Uploading', + }), + retry: i18n.translate('xpack.files.uploadFile.retryButtonLabel', { + defaultMessage: 'Retry', + }), + clear: i18n.translate('xpack.files.uploadFile.clearButtonLabel', { + defaultMessage: 'Clear', + }), + cancel: i18n.translate('xpack.files.uploadFile.cancelButtonLabel', { + defaultMessage: 'Cancel', + }), + uploadDone: i18n.translate('xpack.files.uploadFile.uploadDoneToolTipContent', { + defaultMessage: 'Your file was successfully uploaded!', + }), + fileTooLarge: (expectedSize: string) => + i18n.translate('xpack.files.uploadFile.fileTooLargeErrorMessage', { + defaultMessage: + 'File is too large. Maximum size is {expectedSize, plural, one {# byte} other {# bytes} }.', + values: { expectedSize }, + }), +}; diff --git a/x-pack/plugins/files/public/components/upload_file/index.tsx b/x-pack/plugins/files/public/components/upload_file/index.tsx new file mode 100644 index 0000000000000..4901c46a78c91 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/index.tsx @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { lazy, Suspense } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; +import type { Props } from './upload_file'; + +export type { Props as UploadFileProps }; + +const UploadFileContainer = lazy(() => import('./upload_file')); + +export const UploadFile = (props: Props) => ( + }> + + +); diff --git a/x-pack/plugins/files/public/components/upload_file/upload_file.component.tsx b/x-pack/plugins/files/public/components/upload_file/upload_file.component.tsx new file mode 100644 index 0000000000000..f4f5986d2f00b --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/upload_file.component.tsx @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + EuiText, + EuiSpacer, + EuiFlexItem, + EuiFlexGroup, + EuiFilePicker, + useGeneratedHtmlId, +} from '@elastic/eui'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { css } from '@emotion/react'; +import useObservable from 'react-use/lib/useObservable'; +import { useBehaviorSubject } from '../use_behavior_subject'; +import { i18nTexts } from './i18n_texts'; +import { ControlButton, ClearButton } from './components'; +import { useUploadState } from './context'; + +export interface Props { + meta?: unknown; + accept?: string; + immediate?: boolean; + allowClear?: boolean; + initialFilePromptText?: string; +} + +const { euiFormMaxWidth, euiButtonHeightSmall } = euiThemeVars; + +export const UploadFile = React.forwardRef( + ({ meta, accept, immediate, allowClear = false, initialFilePromptText }, ref) => { + const uploadState = useUploadState(); + const uploading = useBehaviorSubject(uploadState.uploading$); + const error = useBehaviorSubject(uploadState.error$); + const done = useObservable(uploadState.done$); + const isInvalid = Boolean(error); + const errorMessage = error?.message; + + const id = useGeneratedHtmlId({ prefix: 'filesUploadFile' }); + const errorId = `${id}_error`; + + return ( +

+ { + uploadState.setFiles(Array.from(fs ?? [])); + if (immediate) uploadState.upload(meta); + }} + multiple={false} + initialPromptText={initialFilePromptText} + isLoading={uploading} + isInvalid={isInvalid} + accept={accept} + disabled={Boolean(done?.length || uploading)} + aria-describedby={errorMessage ? errorId : undefined} + /> + + + + + + uploadState.upload(meta)} + /> + + {Boolean(!done && !uploading && errorMessage) && ( + + + {errorMessage} + + + )} + {done?.length && allowClear && ( + <> + {/* Occupy middle space */} + + + + + )} + +
+ ); + } +); diff --git a/x-pack/plugins/files/public/components/upload_file/upload_file.stories.tsx b/x-pack/plugins/files/public/components/upload_file/upload_file.stories.tsx new file mode 100644 index 0000000000000..c5a64d6d91a52 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/upload_file.stories.tsx @@ -0,0 +1,141 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { ComponentStory } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; + +import { + FileKindsRegistryImpl, + setFileKindsRegistry, + getFileKindsRegistry, +} from '../../../common/file_kinds_registry'; +import { FilesClient } from '../../types'; +import { FilesContext } from '../context'; +import { UploadFile, Props } from './upload_file'; + +const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms)); +const kind = 'test'; + +const defaultArgs: Props = { + kind, + onDone: action('onDone'), + onError: action('onError'), + client: { + create: async () => ({ file: { id: 'test' } }), + upload: () => sleep(1000), + } as unknown as FilesClient, +}; + +export default { + title: 'stateful/UploadFile', + component: UploadFile, + args: defaultArgs, +}; + +setFileKindsRegistry(new FileKindsRegistryImpl()); + +getFileKindsRegistry().register({ + id: kind, + http: {}, + allowedMimeTypes: ['*'], +}); + +const miniFile = 'miniFile'; +getFileKindsRegistry().register({ + id: miniFile, + http: {}, + maxSizeBytes: 1, + allowedMimeTypes: ['*'], +}); + +const zipOnly = 'zipOnly'; +getFileKindsRegistry().register({ + id: zipOnly, + http: {}, + allowedMimeTypes: ['application/zip'], +}); + +const Template: ComponentStory = (props: Props) => ( + + + +); + +export const Basic = Template.bind({}); + +export const AllowRepeatedUploads = Template.bind({}); +AllowRepeatedUploads.args = { + allowRepeatedUploads: true, +}; + +export const LongErrorUX = Template.bind({}); +LongErrorUX.args = { + client: { + create: async () => ({ file: { id: 'test' } }), + upload: async () => { + await sleep(1000); + throw new Error('Something went wrong while uploading! '.repeat(10).trim()); + }, + delete: async () => {}, + } as unknown as FilesClient, +}; + +export const Abort = Template.bind({}); +Abort.args = { + client: { + create: async () => ({ file: { id: 'test' } }), + upload: async () => { + await sleep(60000); + }, + delete: async () => {}, + } as unknown as FilesClient, +}; + +export const MaxSize = Template.bind({}); +MaxSize.args = { + kind: miniFile, +}; + +export const ZipOnly = Template.bind({}); +ZipOnly.args = { + kind: zipOnly, +}; + +export const AllowClearAfterUpload = Template.bind({}); +AllowClearAfterUpload.args = { + allowClear: true, +}; + +export const ImmediateUpload = Template.bind({}); +ImmediateUpload.args = { + immediate: true, +}; + +export const ImmediateUploadError = Template.bind({}); +ImmediateUploadError.args = { + immediate: true, + client: { + create: async () => ({ file: { id: 'test' } }), + upload: async () => { + await sleep(1000); + throw new Error('Something went wrong while uploading!'); + }, + delete: async () => {}, + } as unknown as FilesClient, +}; + +export const ImmediateUploadAbort = Template.bind({}); +ImmediateUploadAbort.args = { + immediate: true, + client: { + create: async () => ({ file: { id: 'test' } }), + upload: async () => { + await sleep(60000); + }, + delete: async () => {}, + } as unknown as FilesClient, +}; diff --git a/x-pack/plugins/files/public/components/upload_file/upload_file.test.tsx b/x-pack/plugins/files/public/components/upload_file/upload_file.test.tsx new file mode 100644 index 0000000000000..1812f74e180e3 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/upload_file.test.tsx @@ -0,0 +1,203 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { registerTestBed } from '@kbn/test-jest-helpers'; +import { EuiFilePicker } from '@elastic/eui'; + +import { + FileKindsRegistryImpl, + setFileKindsRegistry, + getFileKindsRegistry, +} from '../../../common/file_kinds_registry'; + +import { createMockFilesClient } from '../../mocks'; + +import { FileJSON } from '../../../common'; +import { FilesContext } from '../context'; +import { UploadFile, Props } from './upload_file'; + +describe('UploadFile', () => { + const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms)); + let onDone: jest.Mock; + let onError: jest.Mock; + let client: ReturnType; + + async function initTestBed(props?: Partial) { + const createTestBed = registerTestBed((p: Props) => ( + + + + )); + + const testBed = await createTestBed({ + client, + kind: 'test', + onDone, + onError, + ...props, + }); + + const baseTestSubj = `filesUploadFile`; + + const testSubjects = { + base: baseTestSubj, + uploadButton: `${baseTestSubj}.uploadButton`, + retryButton: `${baseTestSubj}.retryButton`, + cancelButton: `${baseTestSubj}.cancelButton`, + errorMessage: `${baseTestSubj}.error`, + successIcon: `${baseTestSubj}.uploadSuccessIcon`, + }; + + return { + ...testBed, + actions: { + addFiles: (files: File[]) => + act(async () => { + testBed.component.find(EuiFilePicker).props().onChange!(files as unknown as FileList); + await sleep(1); + testBed.component.update(); + }), + upload: (retry = false) => + act(async () => { + testBed + .find(retry ? testSubjects.retryButton : testSubjects.uploadButton) + .simulate('click'); + await sleep(1); + testBed.component.update(); + }), + abort: () => + act(() => { + testBed.find(testSubjects.cancelButton).simulate('click'); + testBed.component.update(); + }), + wait: (ms: number) => + act(async () => { + await sleep(ms); + testBed.component.update(); + }), + }, + testSubjects, + }; + } + + beforeAll(() => { + setFileKindsRegistry(new FileKindsRegistryImpl()); + getFileKindsRegistry().register({ + id: 'test', + maxSizeBytes: 10000, + http: {}, + }); + }); + + beforeEach(() => { + client = createMockFilesClient(); + onDone = jest.fn(); + onError = jest.fn(); + }); + + afterEach(() => { + jest.clearAllMocks(); + jest.restoreAllMocks(); + }); + + it('shows the success message when upload completes', async () => { + client.create.mockResolvedValue({ file: { id: 'test', size: 1 } as FileJSON }); + client.upload.mockResolvedValue({ size: 1, ok: true }); + + const { actions, exists, testSubjects } = await initTestBed(); + await actions.addFiles([{ name: 'test', size: 1 } as File]); + await actions.upload(); + await sleep(1000); + expect(exists(testSubjects.errorMessage)).toBe(false); + expect(exists(testSubjects.successIcon)).toBe(true); + expect(onDone).toHaveBeenCalledTimes(1); + }); + + it('does not show the upload button for "immediate" uploads', async () => { + client.create.mockResolvedValue({ file: { id: 'test' } as FileJSON }); + client.upload.mockImplementation(() => sleep(100).then(() => ({ ok: true, size: 1 }))); + + const { actions, exists, testSubjects } = await initTestBed({ onDone, immediate: true }); + expect(exists(testSubjects.uploadButton)).toBe(false); + await actions.addFiles([{ name: 'test', size: 1 } as File]); + expect(exists(testSubjects.uploadButton)).toBe(false); + await actions.wait(100); + + expect(onDone).toHaveBeenCalledTimes(1); + expect(onError).not.toHaveBeenCalled(); + }); + + it('allows users to cancel uploads', async () => { + client.create.mockResolvedValue({ file: { id: 'test' } as FileJSON }); + client.upload.mockImplementation(() => sleep(1000).then(() => ({ ok: true, size: 1 }))); + + const { actions, testSubjects, find } = await initTestBed(); + await actions.addFiles([{ name: 'test', size: 1 } as File]); + await actions.upload(); + expect(find(testSubjects.cancelButton).props().disabled).toBe(false); + actions.abort(); + + await sleep(1000); + + expect(onDone).not.toHaveBeenCalled(); + expect(onError).not.toHaveBeenCalled(); + }); + + it('does not show error messages while loading', async () => { + client.create.mockResolvedValue({ file: { id: 'test' } as FileJSON }); + client.upload.mockImplementation(async () => { + await sleep(100); + throw new Error('stop!'); + }); + + const { actions, exists, testSubjects } = await initTestBed(); + expect(exists(testSubjects.errorMessage)).toBe(false); + await actions.addFiles([{ name: 'test', size: 1 } as File]); + expect(exists(testSubjects.errorMessage)).toBe(false); + await actions.upload(); + expect(exists(testSubjects.errorMessage)).toBe(false); + await actions.wait(1000); + expect(exists(testSubjects.uploadButton)).toBe(false); // No upload button + expect(exists(testSubjects.errorMessage)).toBe(true); + await actions.upload(true); + expect(exists(testSubjects.errorMessage)).toBe(false); + await actions.wait(500); + expect(exists(testSubjects.errorMessage)).toBe(true); + + expect(onDone).not.toHaveBeenCalled(); + }); + + it('shows error messages if there are any', async () => { + client.create.mockResolvedValue({ file: { id: 'test', size: 10001 } as FileJSON }); + client.upload.mockImplementation(async () => { + await sleep(100); + throw new Error('stop!'); + }); + + const { actions, exists, testSubjects, find } = await initTestBed(); + expect(exists(testSubjects.errorMessage)).toBe(false); + await actions.addFiles([{ name: 'test', size: 1 } as File]); + await actions.upload(); + await actions.wait(1000); + expect(find(testSubjects.errorMessage).text()).toMatch(/stop/i); + expect(onDone).not.toHaveBeenCalled(); + }); + + it('prevents uploads if there is an issue', async () => { + client.create.mockResolvedValue({ file: { id: 'test', size: 10001 } as FileJSON }); + + const { actions, exists, testSubjects, find } = await initTestBed(); + expect(exists(testSubjects.errorMessage)).toBe(false); + await actions.addFiles([{ name: 'test', size: 10001 } as File]); + expect(exists(testSubjects.errorMessage)).toBe(true); + expect(find(testSubjects.errorMessage).text()).toMatch(/File is too large/); + + expect(onDone).not.toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/files/public/components/upload_file/upload_file.tsx b/x-pack/plugins/files/public/components/upload_file/upload_file.tsx new file mode 100644 index 0000000000000..03df4434c548a --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/upload_file.tsx @@ -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 { EuiFilePicker } from '@elastic/eui'; +import React, { type FunctionComponent, useRef, useEffect, useMemo } from 'react'; +import { FilesClient } from '../../types'; + +import { useFilesContext } from '../context'; + +import { UploadFile as Component } from './upload_file.component'; +import { createUploadState } from './upload_state'; +import { context } from './context'; + +/** + * An object representing an uploadded file + */ +interface UploadedFile { + /** + * The ID that was generated for the uploaded file + */ + id: string; + /** + * The kind of the file that was passed in to this component + */ + kind: string; +} + +/** + * UploadFile component props + */ +export interface Props { + /** + * A file kind that should be registered during plugin startup. See {@link FileServiceStart}. + */ + kind: Kind; + /** + * A files client that will be used process uploads. + */ + client: FilesClient; + /** + * Allow users to clear a file after uploading. + * + * @note this will NOT delete an uploaded file. + */ + allowClear?: boolean; + /** + * Start uploading the file as soon as it is provided + * by the user. + */ + immediate?: boolean; + /** + * Metadata that you want to associate with any uploaded files + */ + meta?: Record; + /** + * Whether this component should display a "done" state after processing an + * upload or return to the initial state to allow for another upload. + * + * @default false + */ + allowRepeatedUploads?: boolean; + /** + * Called when the an upload process fully completes + */ + onDone: (files: UploadedFile[]) => void; + + /** + * Called when an error occurs during upload + */ + onError?: (e: Error) => void; +} + +/** + * This component is intended as a wrapper around EuiFilePicker with some opinions + * about upload UX. It is optimised for use in modals, flyouts or forms. + * + * In order to use this component you must register your file kind with {@link FileKindsRegistry} + */ +export const UploadFile = ({ + meta, + client, + onDone, + onError, + allowClear, + kind: kindId, + immediate = false, + allowRepeatedUploads = false, +}: Props): ReturnType => { + const { registry } = useFilesContext(); + const ref = useRef(null); + const uploadState = useMemo( + () => + createUploadState({ + client, + fileKind: registry.get(kindId), + allowRepeatedUploads, + }), + [client, kindId, allowRepeatedUploads, registry] + ); + + /** + * Hook state into component callbacks + */ + useEffect(() => { + const subs = [ + uploadState.clear$.subscribe(() => { + ref.current?.removeFiles(); + }), + uploadState.done$.subscribe((n) => n && onDone(n)), + uploadState.error$.subscribe((e) => e && onError?.(e)), + ]; + return () => subs.forEach((sub) => sub.unsubscribe()); + }, [uploadState, onDone, onError]); + + return ( + + + + ); +}; + +/* eslint-disable import/no-default-export */ +export default UploadFile; diff --git a/x-pack/plugins/files/public/components/upload_file/upload_state.test.ts b/x-pack/plugins/files/public/components/upload_file/upload_state.test.ts new file mode 100644 index 0000000000000..9d7ca8a468be1 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/upload_state.test.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DeeplyMockedKeys } from '@kbn/utility-types-jest'; +import { of, delay, merge, tap, mergeMap } from 'rxjs'; +import { TestScheduler } from 'rxjs/testing'; +import type { FileKind, FileJSON } from '../../../common'; +import { createMockFilesClient } from '../../mocks'; +import type { FilesClient } from '../../types'; + +import { UploadState } from './upload_state'; + +const getTestScheduler = () => + new TestScheduler((actual, expected) => expect(actual).toEqual(expected)); + +describe('UploadState', () => { + let filesClient: DeeplyMockedKeys; + let uploadState: UploadState; + let testScheduler: TestScheduler; + + beforeEach(() => { + filesClient = createMockFilesClient(); + filesClient.create.mockReturnValue(of({ file: { id: 'test' } as FileJSON }) as any); + filesClient.upload.mockReturnValue(of(undefined) as any); + uploadState = new UploadState( + { id: 'test', http: {}, maxSizeBytes: 1000 } as FileKind, + filesClient + ); + testScheduler = getTestScheduler(); + }); + + it('uploads all provided files and reports errors', async () => { + testScheduler.run(({ expectObservable, cold, flush }) => { + const file1 = { name: 'test', size: 1 } as File; + const file2 = { name: 'test 2', size: 1 } as File; + + uploadState.setFiles([file1, file2]); + + // Simulate upload being triggered async + const upload$ = cold('--a|').pipe(tap(uploadState.upload)); + + expectObservable(upload$).toBe('--a|'); + + expectObservable(uploadState.uploading$).toBe('a-(bc)', { + a: false, + b: true, + c: false, + }); + + expectObservable(uploadState.files$).toBe('a-(bc)', { + a: [ + { file: file1, status: 'idle' }, + { file: file2, status: 'idle' }, + ], + b: [ + { file: file1, status: 'uploading' }, + { file: file2, status: 'uploading' }, + ], + c: [ + { file: file1, status: 'uploaded', id: 'test' }, + { file: file2, status: 'uploaded', id: 'test' }, + ], + }); + + flush(); + + expect(filesClient.create).toHaveBeenCalledTimes(2); + expect(filesClient.upload).toHaveBeenCalledTimes(2); + expect(filesClient.delete).not.toHaveBeenCalled(); + }); + }); + + it('attempts to clean up all files when aborting', async () => { + testScheduler.run(({ expectObservable, cold, flush }) => { + filesClient.create.mockReturnValue( + of({ file: { id: 'test' } as FileJSON }).pipe(delay(2)) as any + ); + filesClient.upload.mockReturnValue(of(undefined).pipe(delay(10)) as any); + filesClient.delete.mockReturnValue(of(undefined) as any); + + const file1 = { name: 'test' } as File; + const file2 = { name: 'test 2.png' } as File; + + uploadState.setFiles([file1, file2]); + + // Simulate upload being triggered async + const upload$ = cold('-0|').pipe(tap(() => uploadState.upload({ myMeta: true }))); + const abort$ = cold(' --1|').pipe(tap(uploadState.abort)); + + expectObservable(merge(upload$, abort$)).toBe('-01|'); + + expectObservable(uploadState.error$).toBe('0---', [undefined]); + + expectObservable(uploadState.uploading$).toBe('ab-c', { + a: false, + b: true, + c: false, + }); + + expectObservable(uploadState.files$).toBe('ab-c', { + a: [ + { file: file1, status: 'idle' }, + { file: file2, status: 'idle' }, + ], + b: [ + { file: file1, status: 'uploading' }, + { file: file2, status: 'uploading' }, + ], + c: [ + { file: file1, status: 'upload_failed' }, + { file: file2, status: 'upload_failed' }, + ], + }); + + flush(); + + expect(filesClient.create).toHaveBeenCalledTimes(2); + expect(filesClient.create).toHaveBeenNthCalledWith(1, { + kind: 'test', + meta: { myMeta: true }, + mimeType: undefined, + name: 'test', + }); + expect(filesClient.create).toHaveBeenNthCalledWith(2, { + kind: 'test', + meta: { myMeta: true }, + mimeType: 'image/png', + name: 'test 2', + }); + expect(filesClient.upload).toHaveBeenCalledTimes(2); + expect(filesClient.delete).toHaveBeenCalledTimes(2); + }); + }); + + it('throws for files that are too large', () => { + testScheduler.run(({ expectObservable }) => { + const file = { + name: 'test', + size: 1001, + } as File; + uploadState.setFiles([file]); + expectObservable(uploadState.files$).toBe('a', { + a: [ + { + file, + status: 'idle', + error: new Error('File is too large. Maximum size is 1,000 bytes.'), + }, + ], + }); + }); + }); + + it('option "allowRepeatedUploads" calls clear after upload is done', () => { + testScheduler.run(({ expectObservable, cold }) => { + uploadState = new UploadState( + { id: 'test', http: {}, maxSizeBytes: 1000 } as FileKind, + filesClient, + { allowRepeatedUploads: true } + ); + const file1 = { name: 'test' } as File; + const file2 = { name: 'test 2.png' } as File; + + uploadState.setFiles([file1, file2]); + + const upload$ = cold('-0|').pipe(mergeMap(() => uploadState.upload({ myMeta: true }))); + expectObservable(upload$, ' --^').toBe('---0|', [undefined]); + expectObservable(uploadState.clear$, '^').toBe(' ---0-', [undefined]); + }); + }); +}); diff --git a/x-pack/plugins/files/public/components/upload_file/upload_state.ts b/x-pack/plugins/files/public/components/upload_file/upload_state.ts new file mode 100644 index 0000000000000..aa79db50a1446 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/upload_state.ts @@ -0,0 +1,247 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + of, + map, + zip, + from, + race, + take, + filter, + Subject, + finalize, + forkJoin, + mergeMap, + switchMap, + catchError, + shareReplay, + ReplaySubject, + BehaviorSubject, + type Observable, + combineLatest, + distinctUntilChanged, +} from 'rxjs'; +import type { FileKind, FileJSON } from '../../../common/types'; +import type { FilesClient } from '../../types'; +import { i18nTexts } from './i18n_texts'; + +import { createStateSubject, type SimpleStateSubject, parseFileName } from './util'; + +interface FileState { + file: File; + status: 'idle' | 'uploading' | 'uploaded' | 'upload_failed'; + id?: string; + error?: Error; +} + +type Upload = SimpleStateSubject; + +interface DoneNotification { + id: string; + kind: string; +} + +interface UploadOptions { + allowRepeatedUploads?: boolean; +} + +export class UploadState { + private readonly abort$ = new Subject(); + private readonly files$$ = new BehaviorSubject([]); + + public readonly files$ = this.files$$.pipe( + switchMap((files$) => (files$.length ? zip(...files$) : of([]))) + ); + public readonly clear$ = new Subject(); + public readonly error$ = new BehaviorSubject(undefined); + public readonly uploading$ = new BehaviorSubject(false); + public readonly done$ = new Subject(); + + constructor( + private readonly fileKind: FileKind, + private readonly client: FilesClient, + private readonly opts: UploadOptions = { allowRepeatedUploads: false } + ) { + const latestFiles$ = this.files$$.pipe(switchMap((files$) => combineLatest(files$))); + + latestFiles$ + .pipe( + map((files) => files.some((file) => file.status === 'uploading')), + distinctUntilChanged() + ) + .subscribe(this.uploading$); + + latestFiles$ + .pipe( + map((files) => { + const errorFile = files.find((file) => Boolean(file.error)); + return errorFile ? errorFile.error : undefined; + }), + filter(Boolean) + ) + .subscribe(this.error$); + + latestFiles$ + .pipe( + filter( + (files) => Boolean(files.length) && files.every((file) => file.status === 'uploaded') + ), + map((files) => files.map((file) => ({ id: file.id!, kind: this.fileKind.id }))) + ) + .subscribe(this.done$); + } + + public isUploading(): boolean { + return this.uploading$.getValue(); + } + + private validateFiles(files: File[]): undefined | string { + if ( + this.fileKind.maxSizeBytes != null && + files.some((file) => file.size > this.fileKind.maxSizeBytes!) + ) { + return i18nTexts.fileTooLarge(String(this.fileKind.maxSizeBytes)); + } + return; + } + + public setFiles = (files: File[]): void => { + if (this.isUploading()) { + throw new Error('Cannot update files while uploading'); + } + + if (!files.length) { + this.done$.next(undefined); + this.error$.next(undefined); + } + + const validationError = this.validateFiles(files); + + this.files$$.next( + files.map((file) => + createStateSubject({ + file, + status: 'idle', + error: validationError ? new Error(validationError) : undefined, + }) + ) + ); + }; + + public abort = (): void => { + if (!this.isUploading()) { + throw new Error('No upload in progress'); + } + this.abort$.next(); + }; + + clear = (): void => { + this.setFiles([]); + this.clear$.next(); + }; + + /** + * Do not throw from this method, it is intended to work with {@link forkJoin} from rxjs which + * unsubscribes from all observables if one of them throws. + */ + private uploadFile = ( + file$: SimpleStateSubject, + abort$: Observable, + meta?: unknown + ): Observable => { + const abortController = new AbortController(); + const abortSignal = abortController.signal; + const { file, status } = file$.getValue(); + if (!['idle', 'upload_failed'].includes(status)) { + return of(undefined); + } + + let uploadTarget: undefined | FileJSON; + let erroredOrAborted = false; + + file$.setState({ status: 'uploading', error: undefined }); + + const { name, mime } = parseFileName(file.name); + + return from( + this.client.create({ + kind: this.fileKind.id, + name, + mimeType: mime, + meta: meta as Record, + }) + ).pipe( + mergeMap((result) => { + uploadTarget = result.file; + return race( + abort$.pipe( + map(() => { + abortController.abort(); + throw new Error('Abort!'); + }) + ), + this.client.upload({ + body: file, + id: uploadTarget.id, + kind: this.fileKind.id, + abortSignal, + }) + ); + }), + map(() => { + file$.setState({ status: 'uploaded', id: uploadTarget?.id }); + }), + catchError((e) => { + erroredOrAborted = true; + const isAbortError = e.message === 'Abort!'; + file$.setState({ status: 'upload_failed', error: isAbortError ? undefined : e }); + return of(isAbortError ? undefined : e); + }), + finalize(() => { + if (erroredOrAborted && uploadTarget) { + this.client.delete({ id: uploadTarget.id, kind: this.fileKind.id }); + } + }) + ); + }; + + public upload = (meta?: unknown): Observable => { + if (this.isUploading()) { + throw new Error('Upload already in progress'); + } + const abort$ = new ReplaySubject(1); + const sub = this.abort$.subscribe(abort$); + const upload$ = this.files$$.pipe( + take(1), + switchMap((files$) => { + return forkJoin(files$.map((file$) => this.uploadFile(file$, abort$, meta))); + }), + map(() => undefined), + finalize(() => { + if (this.opts.allowRepeatedUploads) this.clear(); + sub.unsubscribe(); + }), + shareReplay() + ); + + upload$.subscribe(); + + return upload$; + }; +} + +export const createUploadState = ({ + fileKind, + client, + ...options +}: { + fileKind: FileKind; + client: FilesClient; +} & UploadOptions) => { + return new UploadState(fileKind, client, options); +}; diff --git a/x-pack/plugins/files/public/components/upload_file/util/index.ts b/x-pack/plugins/files/public/components/upload_file/util/index.ts new file mode 100644 index 0000000000000..e8fbb4e1ecedc --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/util/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { SimpleStateSubject, createStateSubject } from './simple_state_subject'; + +export { parseFileName } from './parse_file_name'; diff --git a/x-pack/plugins/files/public/components/upload_file/util/parse_file_name.test.ts b/x-pack/plugins/files/public/components/upload_file/util/parse_file_name.test.ts new file mode 100644 index 0000000000000..f03b019f6aca3 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/util/parse_file_name.test.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 { parseFileName } from './parse_file_name'; + +describe('parseFileName', () => { + test('file.png', () => { + expect(parseFileName('file.png')).toEqual({ + name: 'file', + mime: 'image/png', + }); + }); + + test(' Something_* really -=- strange.abc.wav', () => { + expect(parseFileName(' Something_* really -=- strange.abc.wav')).toEqual({ + name: 'Something__ really ___ strange_abc', + mime: 'audio/wave', + }); + }); + + test('!@#$%^&*()', () => { + expect(parseFileName('!@#$%^&*()')).toEqual({ + name: '__________', + mime: undefined, + }); + }); + + test('reallylong.repeat(100).dmg', () => { + expect(parseFileName('reallylong'.repeat(100) + '.dmg')).toEqual({ + name: 'reallylong'.repeat(100).slice(0, 256), + mime: 'application/x-apple-diskimage', + }); + }); +}); diff --git a/x-pack/plugins/files/public/components/upload_file/util/parse_file_name.ts b/x-pack/plugins/files/public/components/upload_file/util/parse_file_name.ts new file mode 100644 index 0000000000000..22e6833851825 --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/util/parse_file_name.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import mime from 'mime-types'; + +interface Result { + name: string; + mime?: string; +} + +export function parseFileName(fileName: string): Result { + const withoutExt = fileName.substring(0, fileName.lastIndexOf('.')) || fileName; + return { + name: withoutExt + .trim() + .slice(0, 256) + .replace(/[^a-z0-9\s]/gi, '_'), // replace invalid chars + mime: mime.lookup(fileName) || undefined, + }; +} diff --git a/x-pack/plugins/files/public/components/upload_file/util/simple_state_subject.ts b/x-pack/plugins/files/public/components/upload_file/util/simple_state_subject.ts new file mode 100644 index 0000000000000..a55259b4962ed --- /dev/null +++ b/x-pack/plugins/files/public/components/upload_file/util/simple_state_subject.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { merge } from 'lodash'; +import { BehaviorSubject } from 'rxjs'; + +export class SimpleStateSubject extends BehaviorSubject { + constructor(initialState: S) { + super(initialState); + } + + public getSnapshot() { + return this.getValue(); + } + + public setState(nextState: Partial): void { + this.next(merge({}, this.getSnapshot(), nextState)); + } +} + +export const createStateSubject = (initialState: S) => + new SimpleStateSubject(initialState); diff --git a/x-pack/plugins/files/public/components/use_behavior_subject.ts b/x-pack/plugins/files/public/components/use_behavior_subject.ts new file mode 100644 index 0000000000000..f68ae6faef28c --- /dev/null +++ b/x-pack/plugins/files/public/components/use_behavior_subject.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BehaviorSubject } from 'rxjs'; +import useObservable from 'react-use/lib/useObservable'; + +export function useBehaviorSubject(o$: BehaviorSubject) { + return useObservable(o$, o$.getValue()); +} diff --git a/x-pack/plugins/files/public/files_client/files_client.ts b/x-pack/plugins/files/public/files_client/files_client.ts index 922846cde2aaf..04e872c654cfc 100644 --- a/x-pack/plugins/files/public/files_client/files_client.ts +++ b/x-pack/plugins/files/public/files_client/files_client.ts @@ -127,12 +127,12 @@ export function createFilesClient({ body: JSON.stringify(body), }); }, - upload: ({ kind, ...args }) => { + upload: ({ kind, abortSignal, ...args }) => { return http.put(apiRoutes.getUploadRoute(scopedFileKind ?? kind, args.id), { headers: { 'Content-Type': 'application/octet-stream', }, - + signal: abortSignal, body: args.body as BodyInit, }); }, diff --git a/x-pack/plugins/files/public/index.ts b/x-pack/plugins/files/public/index.ts index 0c8d9dd242b51..f08b073e7485b 100644 --- a/x-pack/plugins/files/public/index.ts +++ b/x-pack/plugins/files/public/index.ts @@ -13,6 +13,13 @@ export type { FilesClientFactory, FilesClientResponses, } from './types'; +export { + FilesContext, + Image, + type ImageProps, + UploadFile, + type UploadFileProps, +} from './components'; export function plugin() { return new FilesPlugin(); diff --git a/x-pack/plugins/files/public/mocks.ts b/x-pack/plugins/files/public/mocks.ts new file mode 100644 index 0000000000000..c34438d096a2b --- /dev/null +++ b/x-pack/plugins/files/public/mocks.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; +import type { FilesClient } from './types'; + +// TODO: Remove this once we have access to the shared file client mock +export const createMockFilesClient = (): DeeplyMockedKeys => ({ + create: jest.fn(), + delete: jest.fn(), + download: jest.fn(), + find: jest.fn(), + getById: jest.fn(), + getDownloadHref: jest.fn(), + getMetrics: jest.fn(), + getShare: jest.fn(), + list: jest.fn(), + listShares: jest.fn(), + publicDownload: jest.fn(), + share: jest.fn(), + unshare: jest.fn(), + update: jest.fn(), + upload: jest.fn(), +}); diff --git a/x-pack/plugins/files/public/plugin.ts b/x-pack/plugins/files/public/plugin.ts index 22276ba377d8e..688ce0ecbb6a5 100644 --- a/x-pack/plugins/files/public/plugin.ts +++ b/x-pack/plugins/files/public/plugin.ts @@ -6,8 +6,14 @@ */ import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { + getFileKindsRegistry, + setFileKindsRegistry, + FileKindsRegistryImpl, +} from '../common/file_kinds_registry'; import type { FilesClientFactory } from './types'; import { createFilesClient } from './files_client'; +import { FileKind } from '../common'; /** * Public setup-phase contract @@ -18,31 +24,48 @@ export interface FilesSetup { * registered {@link FileKind}. */ filesClientFactory: FilesClientFactory; + + /** + * Register a {@link FileKind} which allows for specifying details about the files + * that will be uploaded. + * + * @param {FileKind} fileKind - the file kind to register + */ + registerFileKind(fileKind: FileKind): void; } -export type FilesStart = FilesSetup; +export type FilesStart = Pick; /** * Bringing files to Kibana */ export class FilesPlugin implements Plugin { - private api: undefined | FilesSetup; + private filesClientFactory: undefined | FilesClientFactory; + + constructor() { + setFileKindsRegistry(new FileKindsRegistryImpl()); + } setup(core: CoreSetup): FilesSetup { - this.api = { - filesClientFactory: { - asScoped(fileKind: string) { - return createFilesClient({ fileKind, http: core.http }); - }, - asUnscoped() { - return createFilesClient({ http: core.http }); - }, + this.filesClientFactory = { + asScoped(fileKind: string) { + return createFilesClient({ fileKind, http: core.http }); + }, + asUnscoped() { + return createFilesClient({ http: core.http }); + }, + }; + return { + filesClientFactory: this.filesClientFactory, + registerFileKind: (fileKind: FileKind) => { + getFileKindsRegistry().register(fileKind); }, }; - return this.api; } start(core: CoreStart): FilesStart { - return this.api!; + return { + filesClientFactory: this.filesClientFactory!, + }; } } diff --git a/x-pack/plugins/files/public/types.ts b/x-pack/plugins/files/public/types.ts index 8a2a67bea8e93..e7a7bd24ce761 100644 --- a/x-pack/plugins/files/public/types.ts +++ b/x-pack/plugins/files/public/types.ts @@ -31,8 +31,8 @@ type UnscopedClientMethodFrom = ( /** * @param args - Input to the endpoint which includes body, params and query of the RESTful endpoint. */ -type ClientMethodFrom = ( - args: Parameters>[0] & { kind: string } +type ClientMethodFrom = ( + args: Parameters>[0] & { kind: string } & ExtraArgs ) => Promise; interface GlobalEndpoints { @@ -96,7 +96,7 @@ export interface FilesClient extends GlobalEndpoints { * * @param args - upload file args */ - upload: ClientMethodFrom; + upload: ClientMethodFrom; /** * Stream a download of the file object's content. * diff --git a/x-pack/plugins/files/server/file/file.test.ts b/x-pack/plugins/files/server/file/file.test.ts index 69f96be79f08b..b2e9167c685b3 100644 --- a/x-pack/plugins/files/server/file/file.test.ts +++ b/x-pack/plugins/files/server/file/file.test.ts @@ -11,7 +11,6 @@ import { elasticsearchServiceMock, loggingSystemMock, savedObjectsServiceMock, - httpServiceMock, } from '@kbn/core/server/mocks'; import { Readable } from 'stream'; import { promisify } from 'util'; @@ -24,7 +23,7 @@ import { FileKindsRegistryImpl, getFileKindsRegistry, setFileKindsRegistry, -} from '../file_kinds_registry'; +} from '../../common/file_kinds_registry'; import { InternalFileShareService } from '../file_share_service'; import { FileMetadataClient } from '../file_client'; import { SavedObjectsFileMetadataClient } from '../file_client/file_metadata_client/adapters/saved_objects'; @@ -41,7 +40,7 @@ describe('File', () => { const fileKind = 'fileKind'; beforeAll(() => { - setFileKindsRegistry(new FileKindsRegistryImpl(httpServiceMock.createRouter())); + setFileKindsRegistry(new FileKindsRegistryImpl()); getFileKindsRegistry().register({ http: {}, id: fileKind }); }); diff --git a/x-pack/plugins/files/server/file_service/file_service_factory.ts b/x-pack/plugins/files/server/file_service/file_service_factory.ts index 4c60145ba42af..cff416e184356 100644 --- a/x-pack/plugins/files/server/file_service/file_service_factory.ts +++ b/x-pack/plugins/files/server/file_service/file_service_factory.ts @@ -28,7 +28,7 @@ import { } from './file_action_types'; import { InternalFileService } from './internal_file_service'; import { FileServiceStart } from './file_service'; -import { FileKindsRegistry } from '../file_kinds_registry'; +import { FileKindsRegistry } from '../../common/file_kinds_registry'; import { SavedObjectsFileMetadataClient } from '../file_client'; /** diff --git a/x-pack/plugins/files/server/file_service/internal_file_service.ts b/x-pack/plugins/files/server/file_service/internal_file_service.ts index a7ba92db9b2e8..4e676fbc26653 100644 --- a/x-pack/plugins/files/server/file_service/internal_file_service.ts +++ b/x-pack/plugins/files/server/file_service/internal_file_service.ts @@ -12,7 +12,7 @@ import { BlobStorageService } from '../blob_storage_service'; import { InternalFileShareService } from '../file_share_service'; import { FileMetadata, File as IFile, FileKind, FileJSON, FilesMetrics } from '../../common'; import { File, toJSON } from '../file'; -import { FileKindsRegistry } from '../file_kinds_registry'; +import { FileKindsRegistry } from '../../common/file_kinds_registry'; import { FileNotFoundError } from './errors'; import type { FileMetadataClient } from '../file_client'; import type { diff --git a/x-pack/plugins/files/server/integration_tests/file_service.test.ts b/x-pack/plugins/files/server/integration_tests/file_service.test.ts index 61196597cc5f9..6277be74e1409 100644 --- a/x-pack/plugins/files/server/integration_tests/file_service.test.ts +++ b/x-pack/plugins/files/server/integration_tests/file_service.test.ts @@ -6,7 +6,6 @@ */ import { CoreStart, ElasticsearchClient } from '@kbn/core/server'; -import { httpServiceMock } from '@kbn/core/server/mocks'; import { createTestServers, createRootWithCorePlugins, @@ -22,7 +21,7 @@ import { FileKindsRegistryImpl, getFileKindsRegistry, setFileKindsRegistry, -} from '../file_kinds_registry'; +} from '../../common/file_kinds_registry'; import { BlobStorageService } from '../blob_storage_service'; import { FileServiceStart, FileServiceFactory } from '../file_service'; import type { CreateFileArgs } from '../file_service/file_action_types'; @@ -52,7 +51,7 @@ describe('FileService', () => { coreSetup = await kbnRoot.setup(); FileServiceFactory.setup(coreSetup.savedObjects); coreStart = await kbnRoot.start(); - setFileKindsRegistry(new FileKindsRegistryImpl(httpServiceMock.createRouter())); + setFileKindsRegistry(new FileKindsRegistryImpl()); const fileKindsRegistry = getFileKindsRegistry(); fileKindsRegistry.register({ id: fileKind, diff --git a/x-pack/plugins/files/server/plugin.ts b/x-pack/plugins/files/server/plugin.ts index ebac15c8f7a0f..08357e28bd3d0 100755 --- a/x-pack/plugins/files/server/plugin.ts +++ b/x-pack/plugins/files/server/plugin.ts @@ -14,17 +14,18 @@ import type { } from '@kbn/core/server'; import { PLUGIN_ID } from '../common/constants'; - -import { BlobStorageService } from './blob_storage_service'; -import { FileServiceFactory } from './file_service'; -import type { FilesPluginSetupDependencies, FilesSetup, FilesStart } from './types'; import { setFileKindsRegistry, getFileKindsRegistry, FileKindsRegistryImpl, -} from './file_kinds_registry'; +} from '../common/file_kinds_registry'; + +import { BlobStorageService } from './blob_storage_service'; +import { FileServiceFactory } from './file_service'; +import type { FilesPluginSetupDependencies, FilesSetup, FilesStart } from './types'; + import type { FilesRequestHandlerContext, FilesRouter } from './routes/types'; -import { registerRoutes } from './routes'; +import { registerRoutes, registerFileKindRoutes } from './routes'; import { Counters, registerUsageCollector } from './usage'; export class FilesPlugin implements Plugin { @@ -62,7 +63,11 @@ export class FilesPlugin implements Plugin { + registerFileKindRoutes(router, fk); + }) + ); registerUsageCollector({ usageCollection, getFileService: () => this.fileServiceFactory?.asInternal(), diff --git a/x-pack/plugins/files/server/routes/common_schemas.ts b/x-pack/plugins/files/server/routes/common_schemas.ts index cd254c5c106c9..6f9b6a5d651a0 100644 --- a/x-pack/plugins/files/server/routes/common_schemas.ts +++ b/x-pack/plugins/files/server/routes/common_schemas.ts @@ -7,8 +7,8 @@ import { schema } from '@kbn/config-schema'; -const ALPHA_NUMERIC_WITH_SPACES_REGEX = /^[a-z0-9\s]+$/i; -const ALPHA_NUMERIC_WITH_SPACES_EXT_REGEX = /^[a-z0-9\s\.]+$/i; +const ALPHA_NUMERIC_WITH_SPACES_REGEX = /^[a-z0-9\s_]+$/i; +const ALPHA_NUMERIC_WITH_SPACES_EXT_REGEX = /^[a-z0-9\s\._]+$/i; function alphanumericValidation(v: string) { return ALPHA_NUMERIC_WITH_SPACES_REGEX.test(v) @@ -19,7 +19,7 @@ function alphanumericValidation(v: string) { function alphanumericWithExtValidation(v: string) { return ALPHA_NUMERIC_WITH_SPACES_EXT_REGEX.test(v) ? undefined - : 'Only alphanumeric characters, spaces (" ") and dots (".") are allowed'; + : 'Only alphanumeric characters, spaces (" "), dots (".") and underscores ("_") are allowed'; } export const fileName = schema.string({ diff --git a/x-pack/plugins/files/server/routes/index.ts b/x-pack/plugins/files/server/routes/index.ts index 5d17cb2292e4c..0a71599ac773e 100644 --- a/x-pack/plugins/files/server/routes/index.ts +++ b/x-pack/plugins/files/server/routes/index.ts @@ -11,6 +11,8 @@ import * as find from './find'; import * as metrics from './metrics'; import * as publicDownload from './public_facing/download'; +export { registerFileKindRoutes } from './file_kind'; + export function registerRoutes(router: FilesRouter) { [find, metrics, publicDownload].forEach((endpoint) => { endpoint.register(router); diff --git a/x-pack/plugins/files/server/test_utils/setup_integration_environment.ts b/x-pack/plugins/files/server/test_utils/setup_integration_environment.ts index 81d04c23bdc96..1c31649d1e8f2 100644 --- a/x-pack/plugins/files/server/test_utils/setup_integration_environment.ts +++ b/x-pack/plugins/files/server/test_utils/setup_integration_environment.ts @@ -13,7 +13,7 @@ import { } from '@kbn/core/test_helpers/kbn_server'; import pRetry from 'p-retry'; import { FileJSON } from '../../common'; -import { getFileKindsRegistry } from '../file_kinds_registry'; +import { getFileKindsRegistry } from '../../common/file_kinds_registry'; export type TestEnvironmentUtils = Awaited>; @@ -93,7 +93,7 @@ export async function setupIntegrationEnvironment() { * Register a test file type */ const testHttpConfig = { tags: ['access:myapp'] }; - getFileKindsRegistry().register({ + const myFileKind = { id: fileKind, blobStoreSettings: { esFixedSizeIndex: { index: testIndex }, @@ -107,7 +107,8 @@ export async function setupIntegrationEnvironment() { list: testHttpConfig, share: testHttpConfig, }, - }); + }; + getFileKindsRegistry().register(myFileKind); const coreStart = await root.start(); const esClient = coreStart.elasticsearch.client.asInternalUser; From 081f53a2206afeedd066dc64e11bf1c00bb5c46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Wed, 21 Sep 2022 14:02:29 +0200 Subject: [PATCH 46/55] [Guided onboarding] Added api functions for the active step (#141045) * [Guided onboarding] Initial service function to check if the step is active and to complete a step * [Guided onboarding] Added unit tests for api and helpers * [Guided onboarding] Added jsdoc comments to the api methods --- .../public/components/main.tsx | 14 +- .../public/components/step_one.tsx | 24 ++-- .../public/components/step_two.tsx | 5 +- src/plugins/guided_onboarding/jest.config.js | 19 +++ .../public/components/onboarding_button.tsx | 2 +- .../constants/{index.ts => guides_config.ts} | 6 +- .../public/services/api.test.ts | 133 ++++++++++++++++++ .../guided_onboarding/public/services/api.ts | 66 ++++++++- .../public/services/helpers.test.ts | 41 ++++++ .../public/services/helpers.ts | 42 ++++++ src/plugins/guided_onboarding/public/types.ts | 6 +- 11 files changed, 323 insertions(+), 35 deletions(-) create mode 100644 src/plugins/guided_onboarding/jest.config.js rename src/plugins/guided_onboarding/public/constants/{index.ts => guides_config.ts} (84%) create mode 100644 src/plugins/guided_onboarding/public/services/api.test.ts create mode 100644 src/plugins/guided_onboarding/public/services/helpers.test.ts create mode 100644 src/plugins/guided_onboarding/public/services/helpers.ts diff --git a/examples/guided_onboarding_example/public/components/main.tsx b/examples/guided_onboarding_example/public/components/main.tsx index 8c372bd066271..157b13f1276c0 100644 --- a/examples/guided_onboarding_example/public/components/main.tsx +++ b/examples/guided_onboarding_example/public/components/main.tsx @@ -10,9 +10,10 @@ import React, { useEffect, useState } from 'react'; import { useHistory } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; +import { CoreStart } from '@kbn/core/public'; import { EuiButton, - EuiFieldNumber, + EuiFieldText, EuiFlexGroup, EuiFlexItem, EuiFormRow, @@ -29,7 +30,6 @@ import { GuidedOnboardingState, UseCase, } from '@kbn/guided-onboarding-plugin/public'; -import { CoreStart } from '@kbn/core/public'; interface MainProps { guidedOnboarding: GuidedOnboardingPluginStart; @@ -51,9 +51,11 @@ export const Main = (props: MainProps) => { ); useEffect(() => { - const subscription = guidedOnboardingApi?.fetchGuideState$().subscribe((newState) => { - setGuideState(newState); - }); + const subscription = guidedOnboardingApi + ?.fetchGuideState$() + .subscribe((newState: GuidedOnboardingState) => { + setGuideState(newState); + }); return () => subscription?.unsubscribe(); }, [guidedOnboardingApi]); @@ -208,7 +210,7 @@ export const Main = (props: MainProps) => {
- setSelectedStep(e.target.value)} /> diff --git a/examples/guided_onboarding_example/public/components/step_one.tsx b/examples/guided_onboarding_example/public/components/step_one.tsx index 65b4d8f1f4ad9..bacb43ad0f67a 100644 --- a/examples/guided_onboarding_example/public/components/step_one.tsx +++ b/examples/guided_onboarding_example/public/components/step_one.tsx @@ -18,6 +18,8 @@ import { EuiSpacer, } from '@elastic/eui'; +import useObservable from 'react-use/lib/useObservable'; + import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types'; interface GuidedOnboardingExampleAppDeps { @@ -28,17 +30,14 @@ export const StepOne = ({ guidedOnboarding }: GuidedOnboardingExampleAppDeps) => const { guidedOnboardingApi } = guidedOnboarding; const [isTourStepOpen, setIsTourStepOpen] = useState(false); - useEffect(() => { - const subscription = guidedOnboardingApi?.fetchGuideState$().subscribe((newState) => { - const { activeGuide: guide, activeStep: step } = newState; - - if (guide === 'search' && step === 'add_data') { - setIsTourStepOpen(true); - } - }); - return () => subscription?.unsubscribe(); - }, [guidedOnboardingApi]); + const isTourActive = useObservable( + guidedOnboardingApi!.isGuideStepActive$('search', 'add_data'), + false + ); + useEffect(() => { + setIsTourStepOpen(isTourActive); + }, [isTourActive]); return ( <> @@ -79,10 +78,7 @@ export const StepOne = ({ guidedOnboarding }: GuidedOnboardingExampleAppDeps) => > { - await guidedOnboardingApi?.updateGuideState({ - activeGuide: 'search', - activeStep: 'search_experience', - }); + await guidedOnboardingApi?.completeGuideStep('search', 'add_data'); }} > Complete step 1 diff --git a/examples/guided_onboarding_example/public/components/step_two.tsx b/examples/guided_onboarding_example/public/components/step_two.tsx index d5962dc5e1cd9..a9f9388d567fc 100644 --- a/examples/guided_onboarding_example/public/components/step_two.tsx +++ b/examples/guided_onboarding_example/public/components/step_two.tsx @@ -80,10 +80,7 @@ export const StepTwo = (props: StepTwoProps) => { > { - await guidedOnboardingApi?.updateGuideState({ - activeGuide: 'search', - activeStep: 'optimize', - }); + await guidedOnboardingApi?.completeGuideStep('search', 'search_experience'); }} > Complete step 2 diff --git a/src/plugins/guided_onboarding/jest.config.js b/src/plugins/guided_onboarding/jest.config.js new file mode 100644 index 0000000000000..dbff307ed09e4 --- /dev/null +++ b/src/plugins/guided_onboarding/jest.config.js @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../..', + roots: ['/src/plugins/guided_onboarding'], + testRunner: 'jasmine2', + coverageDirectory: '/target/kibana-coverage/jest/src/plugins/guided_onboarding', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/src/plugins/guided_onboarding/{common,public,server}/**/*.{ts,tsx}', + ], +}; diff --git a/src/plugins/guided_onboarding/public/components/onboarding_button.tsx b/src/plugins/guided_onboarding/public/components/onboarding_button.tsx index bab27ec007a19..8dde62411f1c1 100644 --- a/src/plugins/guided_onboarding/public/components/onboarding_button.tsx +++ b/src/plugins/guided_onboarding/public/components/onboarding_button.tsx @@ -31,7 +31,7 @@ import { import { ApplicationStart } from '@kbn/core-application-browser'; import { HttpStart } from '@kbn/core-http-browser'; import { i18n } from '@kbn/i18n'; -import { guidesConfig } from '../constants'; +import { guidesConfig } from '../constants/guides_config'; import type { GuideConfig, StepStatus, GuidedOnboardingState, StepConfig } from '../types'; import type { ApiService } from '../services/api'; diff --git a/src/plugins/guided_onboarding/public/constants/index.ts b/src/plugins/guided_onboarding/public/constants/guides_config.ts similarity index 84% rename from src/plugins/guided_onboarding/public/constants/index.ts rename to src/plugins/guided_onboarding/public/constants/guides_config.ts index 700f035c8c8dd..0cbee9d4b12b6 100644 --- a/src/plugins/guided_onboarding/public/constants/index.ts +++ b/src/plugins/guided_onboarding/public/constants/guides_config.ts @@ -6,14 +6,10 @@ * Side Public License, v 1. */ +import { GuidesConfig } from '../types'; import { securityConfig } from './security'; import { observabilityConfig } from './observability'; import { searchConfig } from './search'; -import type { GuideConfig, UseCase } from '../types'; - -type GuidesConfig = { - [key in UseCase]: GuideConfig; -}; export const guidesConfig: GuidesConfig = { security: securityConfig, diff --git a/src/plugins/guided_onboarding/public/services/api.test.ts b/src/plugins/guided_onboarding/public/services/api.test.ts new file mode 100644 index 0000000000000..ff614fc8da78c --- /dev/null +++ b/src/plugins/guided_onboarding/public/services/api.test.ts @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { HttpSetup } from '@kbn/core/public'; +import { httpServiceMock } from '@kbn/core/public/mocks'; +import { firstValueFrom, Subscription } from 'rxjs'; + +import { API_BASE_PATH } from '../../common'; +import { ApiService } from './api'; +import { GuidedOnboardingState } from '..'; + +const searchGuide = 'search'; +const firstStep = 'add_data'; +const secondStep = 'search_experience'; +const lastStep = 'review'; + +describe('GuidedOnboarding ApiService', () => { + let httpClient: jest.Mocked; + let apiService: ApiService; + let subscription: Subscription; + + beforeEach(() => { + httpClient = httpServiceMock.createStartContract({ basePath: '/base/path' }); + httpClient.get.mockResolvedValue({ + state: { activeGuide: searchGuide, activeStep: firstStep }, + }); + apiService = new ApiService(); + apiService.setup(httpClient); + }); + + afterEach(() => { + if (subscription) { + subscription.unsubscribe(); + } + jest.restoreAllMocks(); + }); + + describe('fetchGuideState$', () => { + it('sends a request to the get API', () => { + subscription = apiService.fetchGuideState$().subscribe(); + expect(httpClient.get).toHaveBeenCalledTimes(1); + expect(httpClient.get).toHaveBeenCalledWith(`${API_BASE_PATH}/state`); + }); + + it('broadcasts the updated state', async () => { + await apiService.updateGuideState({ + activeGuide: searchGuide, + activeStep: secondStep, + }); + + const state = await firstValueFrom(apiService.fetchGuideState$()); + expect(state).toEqual({ activeGuide: searchGuide, activeStep: secondStep }); + }); + }); + + describe('updateGuideState', () => { + it('sends a request to the put API', async () => { + const state = { + activeGuide: searchGuide, + activeStep: secondStep, + }; + await apiService.updateGuideState(state as GuidedOnboardingState); + expect(httpClient.put).toHaveBeenCalledTimes(1); + expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, { + body: JSON.stringify(state), + }); + }); + }); + + describe('isGuideStepActive$', () => { + it('returns true if the step is active', async (done) => { + subscription = apiService + .isGuideStepActive$(searchGuide, firstStep) + .subscribe((isStepActive) => { + if (isStepActive) { + done(); + } + }); + }); + + it('returns false if the step is not active', async (done) => { + subscription = apiService + .isGuideStepActive$(searchGuide, secondStep) + .subscribe((isStepActive) => { + if (!isStepActive) { + done(); + } + }); + }); + }); + + describe('completeGuideStep', () => { + it(`completes the step when it's active`, async () => { + await apiService.completeGuideStep(searchGuide, firstStep); + expect(httpClient.put).toHaveBeenCalledTimes(1); + // this assertion depends on the guides config, we are checking for the next step + expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, { + body: JSON.stringify({ + activeGuide: searchGuide, + activeStep: secondStep, + }), + }); + }); + + it(`completes the guide when the last step is active`, async () => { + httpClient.get.mockResolvedValue({ + // this state depends on the guides config + state: { activeGuide: searchGuide, activeStep: lastStep }, + }); + apiService.setup(httpClient); + + await apiService.completeGuideStep(searchGuide, lastStep); + expect(httpClient.put).toHaveBeenCalledTimes(1); + // this assertion depends on the guides config, we are checking for the last step + expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, { + body: JSON.stringify({ + activeGuide: searchGuide, + activeStep: 'completed', + }), + }); + }); + + it(`does nothing if the step is not active`, async () => { + await apiService.completeGuideStep(searchGuide, secondStep); + expect(httpClient.put).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/src/plugins/guided_onboarding/public/services/api.ts b/src/plugins/guided_onboarding/public/services/api.ts index 543b4ffc30f41..b99975c3a837a 100644 --- a/src/plugins/guided_onboarding/public/services/api.ts +++ b/src/plugins/guided_onboarding/public/services/api.ts @@ -7,10 +7,11 @@ */ import { HttpSetup } from '@kbn/core/public'; -import { BehaviorSubject, map, from, concatMap, of } from 'rxjs'; +import { BehaviorSubject, map, from, concatMap, of, Observable, firstValueFrom } from 'rxjs'; import { API_BASE_PATH } from '../../common'; -import { GuidedOnboardingState } from '../types'; +import { GuidedOnboardingState, UseCase } from '../types'; +import { getNextStep, isLastStep } from './helpers'; export class ApiService { private client: HttpSetup | undefined; @@ -21,7 +22,12 @@ export class ApiService { this.onboardingGuideState$ = new BehaviorSubject(undefined); } - public fetchGuideState$() { + /** + * An Observable with the guided onboarding state. + * Initially the state is fetched from the backend. + * Subsequently, the observable is updated automatically, when the state changes. + */ + public fetchGuideState$(): Observable { // TODO add error handling if this.client has not been initialized or request fails return this.onboardingGuideState$.pipe( concatMap((state) => @@ -34,7 +40,14 @@ export class ApiService { ); } - public async updateGuideState(newState: GuidedOnboardingState) { + /** + * Updates the state of the guided onboarding + * @param {GuidedOnboardingState} newState the new state of the guided onboarding + * @return {Promise} a promise with the updated state or undefined if the update fails + */ + public async updateGuideState( + newState: GuidedOnboardingState + ): Promise<{ state: GuidedOnboardingState } | undefined> { if (!this.client) { throw new Error('ApiService has not be initialized.'); } @@ -54,6 +67,51 @@ export class ApiService { console.error(error); } } + + /** + * An observable with the boolean value if the step is active. + * Returns true, if the passed params identify the guide step that is currently active. + * Returns false otherwise. + * @param {string} guideID the id of the guide (one of search, observability, security) + * @param {string} stepID the id of the step in the guide + * @return {Observable} an observable with the boolean value + */ + public isGuideStepActive$(guideID: string, stepID: string): Observable { + return this.fetchGuideState$().pipe( + map((state) => { + return state ? state.activeGuide === guideID && state.activeStep === stepID : false; + }) + ); + } + + /** + * Completes the guide step identified by the passed params. + * A noop if the passed step is not active. + * Completes the current guide, if the step is the last one in the guide. + * @param {string} guideID the id of the guide (one of search, observability, security) + * @param {string} stepID the id of the step in the guide + * @return {Promise} a promise with the updated state or undefined if the operation fails + */ + public async completeGuideStep( + guideID: string, + stepID: string + ): Promise<{ state: GuidedOnboardingState } | undefined> { + const isStepActive = await firstValueFrom(this.isGuideStepActive$(guideID, stepID)); + if (isStepActive) { + if (isLastStep(guideID, stepID)) { + await this.updateGuideState({ activeGuide: guideID as UseCase, activeStep: 'completed' }); + } else { + const nextStepID = getNextStep(guideID, stepID); + if (nextStepID !== undefined) { + await this.updateGuideState({ + activeGuide: guideID as UseCase, + activeStep: nextStepID, + }); + } + } + } + return undefined; + } } export const apiService = new ApiService(); diff --git a/src/plugins/guided_onboarding/public/services/helpers.test.ts b/src/plugins/guided_onboarding/public/services/helpers.test.ts new file mode 100644 index 0000000000000..3f2ea164bd25d --- /dev/null +++ b/src/plugins/guided_onboarding/public/services/helpers.test.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { getNextStep, isLastStep } from './helpers'; + +describe('GuidedOnboarding ApiService helpers', () => { + // this test suite depends on the guides config + describe('isLastStepActive', () => { + it('returns true if the passed params are for the last step', () => { + const result = isLastStep('search', 'review'); + expect(result).toBe(true); + }); + + it('returns false if the passed params are not for the last step', () => { + const result = isLastStep('search', 'add_data'); + expect(result).toBe(false); + }); + }); + + describe('getNextStep', () => { + it('returns id of the next step', () => { + const result = getNextStep('search', 'add_data'); + expect(result).toEqual('search_experience'); + }); + + it('returns undefined if the params are not part of the config', () => { + const result = getNextStep('some_guide', 'some_step'); + expect(result).toBeUndefined(); + }); + + it(`returns undefined if it's the last step`, () => { + const result = getNextStep('search', 'review'); + expect(result).toBeUndefined(); + }); + }); +}); diff --git a/src/plugins/guided_onboarding/public/services/helpers.ts b/src/plugins/guided_onboarding/public/services/helpers.ts new file mode 100644 index 0000000000000..81020adab0cd6 --- /dev/null +++ b/src/plugins/guided_onboarding/public/services/helpers.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { guidesConfig } from '../constants/guides_config'; +import { GuideConfig, StepConfig, UseCase } from '../types'; + +const getGuideConfig = (guideID?: string): GuideConfig | undefined => { + if (guideID && Object.keys(guidesConfig).includes(guideID)) { + return guidesConfig[guideID as UseCase]; + } +}; + +const getStepIndex = (guideID: string, stepID: string): number => { + const guide = getGuideConfig(guideID); + if (guide) { + return guide.steps.findIndex((step: StepConfig) => step.id === stepID); + } + return -1; +}; + +export const isLastStep = (guideID: string, stepID: string): boolean => { + const guide = getGuideConfig(guideID); + const activeStepIndex = getStepIndex(guideID, stepID); + const stepsNumber = guide?.steps.length || 0; + if (stepsNumber > 0) { + return activeStepIndex === stepsNumber - 1; + } + return false; +}; + +export const getNextStep = (guideID: string, stepID: string): string | undefined => { + const guide = getGuideConfig(guideID); + const activeStepIndex = getStepIndex(guideID, stepID); + if (activeStepIndex > -1 && guide?.steps[activeStepIndex + 1]) { + return guide?.steps[activeStepIndex + 1].id; + } +}; diff --git a/src/plugins/guided_onboarding/public/types.ts b/src/plugins/guided_onboarding/public/types.ts index 8beb1772a511e..1e9fd7ab76574 100755 --- a/src/plugins/guided_onboarding/public/types.ts +++ b/src/plugins/guided_onboarding/public/types.ts @@ -44,9 +44,13 @@ export interface GuideConfig { steps: StepConfig[]; } +export type GuidesConfig = { + [key in UseCase]: GuideConfig; +}; + export interface GuidedOnboardingState { activeGuide: UseCase | 'unset'; - activeStep: string | 'unset'; + activeStep: string | 'unset' | 'completed'; } export interface ClientConfigType { From da8a70353cc87fbc6c8a5ae5b64194c60a63b807 Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Wed, 21 Sep 2022 15:44:16 +0300 Subject: [PATCH 47/55] [TSVB] When using annotations from different data view than the visualization, the panel breaks (#141104) * [TSVB] When using annotations from different data view than the visualization, the panel breaks Closes: #140816 * Update get_vis_data.ts * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../timeseries/server/lib/get_vis_data.ts | 48 ++++++++++++++----- .../annotations/get_request_params.ts | 19 +++++++- ...timefield.test.ts => get_interval.test.ts} | 14 +++--- ...erval_and_timefield.ts => get_interval.ts} | 24 ++-------- .../series/date_histogram.test.js | 18 +++---- 5 files changed, 73 insertions(+), 50 deletions(-) rename src/plugins/vis_types/timeseries/server/lib/vis_data/{get_interval_and_timefield.test.ts => get_interval.test.ts} (69%) rename src/plugins/vis_types/timeseries/server/lib/vis_data/{get_interval_and_timefield.ts => get_interval.ts} (63%) diff --git a/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts b/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts index 360256ccb628b..9854472c1dc3f 100644 --- a/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts +++ b/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts @@ -8,6 +8,8 @@ import _ from 'lodash'; +import { validateField } from '../../common/fields_utils'; +import { TimeFieldNotSpecifiedError } from '../../common/errors'; import { Framework } from '../plugin'; import type { TimeseriesVisData, FetchedIndexPattern, Series } from '../../common/types'; import { PANEL_TYPES } from '../../common/enums'; @@ -20,7 +22,7 @@ import { getSeriesData } from './vis_data/get_series_data'; import { getTableData } from './vis_data/get_table_data'; import { getEsQueryConfig } from './vis_data/helpers/get_es_query_uisettings'; import { getCachedIndexPatternFetcher } from './search_strategies/lib/cached_index_pattern_fetcher'; -import { getIntervalAndTimefield } from './vis_data/get_interval_and_timefield'; +import { getInterval } from './vis_data/get_interval'; import { UI_SETTINGS } from '../../common/constants'; export async function getVisData( @@ -60,16 +62,40 @@ export async function getVisData( const maxBuckets = await uiSettings.get(UI_SETTINGS.MAX_BUCKETS_SETTING); const { min, max } = request.body.timerange; - return getIntervalAndTimefield( - panel, - index, - { - min, - max, - maxBuckets, - }, - series - ); + let timeField = + (series?.override_index_pattern ? series.series_time_field : panel.time_field) || + index.indexPattern?.timeFieldName; + + /** This code is historically in TSVB and for backward compatibility + * we cannot remove it while we support String Indexes. + * Case: only for String Indexes mode + if user doesn't provide timeField + * we should use @timestamp as default timeField **/ + if (!panel.use_kibana_indexes && !timeField) { + timeField = '@timestamp'; + } + + if (panel.use_kibana_indexes) { + if (timeField) { + validateField(timeField, index); + } else { + throw new TimeFieldNotSpecifiedError(); + } + } + + return { + timeField, + ...getInterval( + timeField!, + panel, + index, + { + min, + max, + maxBuckets, + }, + series + ), + }; }, }; diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/annotations/get_request_params.ts b/src/plugins/vis_types/timeseries/server/lib/vis_data/annotations/get_request_params.ts index 815598007030d..f86ec121683a9 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/annotations/get_request_params.ts +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/annotations/get_request_params.ts @@ -6,6 +6,8 @@ * Side Public License, v 1. */ import { i18n } from '@kbn/i18n'; +import { getInterval } from '../get_interval'; +import { UI_SETTINGS } from '../../../../common/constants'; import type { Annotation, Panel } from '../../../../common/types'; import { buildAnnotationRequest } from './build_request_body'; import type { @@ -31,7 +33,6 @@ export async function getAnnotationRequestParams( capabilities, uiSettings, cachedIndexPatternFetcher, - buildSeriesMetaParams, }: AnnotationServices ): Promise { const annotationIndex = await cachedIndexPatternFetcher(annotation.index_pattern); @@ -44,7 +45,21 @@ export async function getAnnotationRequestParams( annotationIndex, capabilities, uiSettings, - getMetaParams: () => buildSeriesMetaParams(annotationIndex, Boolean(panel.use_kibana_indexes)), + getMetaParams: async () => { + const maxBuckets = await uiSettings.get(UI_SETTINGS.MAX_BUCKETS_SETTING); + const { min, max } = req.body.timerange; + const timeField = + annotation.time_field ?? annotationIndex.indexPattern?.timeFieldName ?? panel.time_field; + + return { + timeField, + ...getInterval(timeField!, panel, annotationIndex, { + min, + max, + maxBuckets, + }), + }; + }, }); return { diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.test.ts b/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval.test.ts similarity index 69% rename from src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.test.ts rename to src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval.test.ts index 45e0b410b6a6b..bcd3ea99e4f21 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.test.ts +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import { getIntervalAndTimefield } from './get_interval_and_timefield'; +import { getInterval } from './get_interval'; import { FetchedIndexPattern, Panel, Series } from '../../../common/types'; -describe('getIntervalAndTimefield(panel, series)', () => { +describe('getInterval', () => { const index: FetchedIndexPattern = {} as FetchedIndexPattern; const params = { min: '2017-01-01T00:00:00Z', @@ -17,17 +17,16 @@ describe('getIntervalAndTimefield(panel, series)', () => { maxBuckets: 1000, }; - test('returns the panel interval and timefield', () => { + test('returns the panel interval', () => { const panel = { time_field: '@timestamp', interval: 'auto' } as Panel; const series = {} as Series; - expect(getIntervalAndTimefield(panel, index, params, series)).toEqual({ - timeField: '@timestamp', + expect(getInterval('@timestamp', panel, index, params, series)).toEqual({ interval: 'auto', }); }); - test('returns the series interval and timefield', () => { + test('returns the series interval', () => { const panel = { time_field: '@timestamp', interval: 'auto' } as Panel; const series = { override_index_pattern: true, @@ -35,8 +34,7 @@ describe('getIntervalAndTimefield(panel, series)', () => { series_time_field: 'time', } as unknown as Series; - expect(getIntervalAndTimefield(panel, index, params, series)).toEqual({ - timeField: 'time', + expect(getInterval('@timestamp', panel, index, params, series)).toEqual({ interval: '1m', }); }); diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.ts b/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval.ts similarity index 63% rename from src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.ts rename to src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval.ts index af6eb44affabc..593eb30b7a9aa 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.ts +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval.ts @@ -5,11 +5,10 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import moment from 'moment'; import { AUTO_INTERVAL } from '../../../common/constants'; -import { validateField } from '../../../common/fields_utils'; import { validateInterval } from '../../../common/validate_interval'; -import { TimeFieldNotSpecifiedError } from '../../../common/errors'; import type { FetchedIndexPattern, Panel, Series } from '../../../common/types'; @@ -19,29 +18,13 @@ interface IntervalParams { maxBuckets: number; } -export function getIntervalAndTimefield( +export function getInterval( + timeField: string, panel: Panel, index: FetchedIndexPattern, { min, max, maxBuckets }: IntervalParams, series?: Series ) { - let timeField = - (series?.override_index_pattern ? series.series_time_field : panel.time_field) || - index.indexPattern?.timeFieldName; - - // should use @timestamp as default timeField for es indeces if user doesn't provide timeField - if (!panel.use_kibana_indexes && !timeField) { - timeField = '@timestamp'; - } - - if (panel.use_kibana_indexes) { - if (timeField) { - validateField(timeField, index); - } else { - throw new TimeFieldNotSpecifiedError(); - } - } - let interval = panel.interval; let maxBars = panel.max_bars; @@ -61,7 +44,6 @@ export function getIntervalAndTimefield( return { maxBars, - timeField, interval: interval || AUTO_INTERVAL, }; } diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js b/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js index ece2b2d316eda..debe2b5cbdf19 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/series/date_histogram.test.js @@ -8,7 +8,7 @@ import { DefaultSearchCapabilities } from '../../../search_strategies/capabilities/default_search_capabilities'; import { dateHistogram } from './date_histogram'; -import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; +import { getInterval } from '../../get_interval'; import { UI_SETTINGS } from '@kbn/data-plugin/common'; describe('dateHistogram(req, panel, series)', () => { @@ -46,8 +46,10 @@ describe('dateHistogram(req, panel, series)', () => { uiSettings = { get: async (key) => (key === UI_SETTINGS.HISTOGRAM_MAX_BARS ? 100 : 50), }; - buildSeriesMetaParams = jest.fn(async () => { - return getIntervalAndTimefield( + buildSeriesMetaParams = jest.fn(async () => ({ + timeField: '@timestamp', + ...getInterval( + '@timestamp', panel, indexPattern, { @@ -56,8 +58,8 @@ describe('dateHistogram(req, panel, series)', () => { maxBuckets: 1000, }, series - ); - }); + ), + })); }); test('calls next when finished', async () => { @@ -163,7 +165,7 @@ describe('dateHistogram(req, panel, series)', () => { test('returns valid date histogram with overridden index pattern', async () => { series.override_index_pattern = 1; series.series_index_pattern = '*'; - series.series_time_field = 'timestamp'; + series.series_time_field = '@timestamp'; series.series_interval = '20s'; const next = (doc) => doc; const doc = await dateHistogram( @@ -183,7 +185,7 @@ describe('dateHistogram(req, panel, series)', () => { aggs: { timeseries: { date_histogram: { - field: 'timestamp', + field: '@timestamp', fixed_interval: '20s', min_doc_count: 0, time_zone: 'UTC', @@ -196,7 +198,7 @@ describe('dateHistogram(req, panel, series)', () => { }, meta: { intervalString: '20s', - timeField: 'timestamp', + timeField: '@timestamp', seriesId: 'test', panelId: 'panelId', }, From 6ac80cb649b9fb994184f492144aae81780834f7 Mon Sep 17 00:00:00 2001 From: ofiriro3 Date: Wed, 21 Sep 2022 16:14:58 +0300 Subject: [PATCH 48/55] Creating ingest pipepline for the latest index (#141095) --- .../common/constants.ts | 2 + .../server/create_indices/create_indices.ts | 27 ++++++---- .../server/create_indices/create_processor.ts | 30 +++-------- .../server/create_indices/ingest_pipelines.ts | 54 +++++++++++++++++++ 4 files changed, 80 insertions(+), 33 deletions(-) create mode 100644 x-pack/plugins/cloud_security_posture/server/create_indices/ingest_pipelines.ts diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index 240d14c4b573c..764cb49dae8d2 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -30,6 +30,8 @@ export const BENCHMARK_SCORE_INDEX_PATTERN = 'logs-cloud_security_posture.scores export const BENCHMARK_SCORE_INDEX_DEFAULT_NS = 'logs-cloud_security_posture.scores-default'; export const CSP_INGEST_TIMESTAMP_PIPELINE = 'cloud_security_posture_add_ingest_timestamp_pipeline'; +export const CSP_LATEST_FINDINGS_INGEST_TIMESTAMP_PIPELINE = + 'cloud_security_posture_latest_index_add_ingest_timestamp_pipeline'; export const RULE_PASSED = `passed`; export const RULE_FAILED = `failed`; diff --git a/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts b/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts index 62deda2b9ee3f..d34678acdc845 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts @@ -11,7 +11,6 @@ import { BENCHMARK_SCORE_INDEX_PATTERN, BENCHMARK_SCORE_INDEX_TEMPLATE_NAME, CLOUD_SECURITY_POSTURE_PACKAGE_NAME, - CSP_INGEST_TIMESTAMP_PIPELINE, FINDINGS_INDEX_NAME, LATEST_FINDINGS_INDEX_DEFAULT_NS, LATEST_FINDINGS_INDEX_PATTERN, @@ -19,11 +18,15 @@ import { } from '../../common/constants'; import { createPipelineIfNotExists } from './create_processor'; import { benchmarkScoreMapping } from './benchmark_score_mapping'; +import { latestFindingsPipelineIngestConfig, scorePipelineIngestConfig } from './ingest_pipelines'; // TODO: Add integration tests export const initializeCspIndices = async (esClient: ElasticsearchClient, logger: Logger) => { - await createPipelineIfNotExists(esClient, CSP_INGEST_TIMESTAMP_PIPELINE, logger); + await Promise.all([ + createPipelineIfNotExists(esClient, scorePipelineIngestConfig, logger), + createPipelineIfNotExists(esClient, latestFindingsPipelineIngestConfig, logger), + ]); return Promise.all([ createLatestFindingsIndex(esClient, logger), @@ -44,7 +47,7 @@ const createBenchmarkScoreIndex = async (esClient: ElasticsearchClient, logger: template: { mappings: benchmarkScoreMapping, settings: { - default_pipeline: CSP_INGEST_TIMESTAMP_PIPELINE, + default_pipeline: scorePipelineIngestConfig.id, lifecycle: { // This is the default lifecycle name, it is named on the data-stream type (e.g, logs/ metrics) name: 'logs', @@ -84,20 +87,24 @@ const createLatestFindingsIndex = async (esClient: ElasticsearchClient, logger: const { template, composed_of, _meta } = findingsIndexTemplateResponse.index_templates[0].index_template; - if (template?.settings) { - template.settings.lifecycle = { - name: '', - }; - } - // We always want to keep the index template updated await esClient.indices.putIndexTemplate({ name: LATEST_FINDINGS_INDEX_TEMPLATE_NAME, index_patterns: LATEST_FINDINGS_INDEX_PATTERN, priority: 500, + template: { + mappings: template?.mappings, + settings: { + ...template?.settings, + default_pipeline: latestFindingsPipelineIngestConfig.id, + lifecycle: { + name: '', + }, + }, + aliases: template?.aliases, + }, _meta, composed_of, - template, }); await createIndexSafe(esClient, logger, LATEST_FINDINGS_INDEX_DEFAULT_NS); diff --git a/x-pack/plugins/cloud_security_posture/server/create_indices/create_processor.ts b/x-pack/plugins/cloud_security_posture/server/create_indices/create_processor.ts index 704765afc976c..19755bc326039 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_indices/create_processor.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_indices/create_processor.ts @@ -6,17 +6,20 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; +import { IngestPutPipelineRequest } from '@elastic/elasticsearch/lib/api/types'; /** - * @param pipelineId - the pipeline id to create. If a pipeline with the same pipelineId already exists, nothing is created or updated. - * + * @param logger - logger + * @param pipelineConf - ingest pipeline configuration + * @param esClient - the elasticsearch client * @return true if the pipeline exits or created, false otherwise. */ export const createPipelineIfNotExists = async ( esClient: ElasticsearchClient, - pipelineId: string, + pipelineConf: IngestPutPipelineRequest, logger: Logger ) => { + const pipelineId = pipelineConf.id; try { await esClient.ingest.getPipeline({ id: pipelineId }); logger.trace(`pipeline: ${pipelineId} already exists`); @@ -25,26 +28,7 @@ export const createPipelineIfNotExists = async ( const exitError = transformError(exitErr); if (exitError.statusCode === 404) { try { - await esClient.ingest.putPipeline({ - id: pipelineId, - description: 'Pipeline for adding event timestamp', - processors: [ - { - set: { - field: '@timestamp', - value: '{{_ingest.timestamp}}', - }, - }, - ], - on_failure: [ - { - set: { - field: 'error.message', - value: '{{ _ingest.on_failure_message }}', - }, - }, - ], - }); + await esClient.ingest.putPipeline(pipelineConf); logger.trace(`pipeline: ${pipelineId} was created`); return true; } catch (existError) { diff --git a/x-pack/plugins/cloud_security_posture/server/create_indices/ingest_pipelines.ts b/x-pack/plugins/cloud_security_posture/server/create_indices/ingest_pipelines.ts new file mode 100644 index 0000000000000..7948fd9d90578 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/create_indices/ingest_pipelines.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IngestPutPipelineRequest } from '@elastic/elasticsearch/lib/api/types'; +import { + CSP_INGEST_TIMESTAMP_PIPELINE, + CSP_LATEST_FINDINGS_INGEST_TIMESTAMP_PIPELINE, +} from '../../common/constants'; + +export const scorePipelineIngestConfig: IngestPutPipelineRequest = { + id: CSP_INGEST_TIMESTAMP_PIPELINE, + description: 'Pipeline for adding event timestamp', + processors: [ + { + set: { + field: '@timestamp', + value: '{{_ingest.timestamp}}', + }, + }, + ], + on_failure: [ + { + set: { + field: 'error.message', + value: '{{ _ingest.on_failure_message }}', + }, + }, + ], +}; + +export const latestFindingsPipelineIngestConfig: IngestPutPipelineRequest = { + id: CSP_LATEST_FINDINGS_INGEST_TIMESTAMP_PIPELINE, + description: 'Pipeline for cloudbeat latest findings index', + processors: [ + { + set: { + field: 'event.ingested', + value: '{{_ingest.timestamp}}', + }, + }, + ], + on_failure: [ + { + set: { + field: 'error.message', + value: '{{ _ingest.on_failure_message }}', + }, + }, + ], +}; From f3331b92b4c453923a6e8db0e48a2a4b36a133c8 Mon Sep 17 00:00:00 2001 From: Abdul Wahab Zahid Date: Wed, 21 Sep 2022 15:29:24 +0200 Subject: [PATCH 49/55] [Uptime] Fix: Adjust tooltip on Run test button for Private Locations (#138863) * Control popover logic with MouseOver and MouseOut to be able to show popover on a disabled button. * Run "Test now" only on public locations. * Show specific tooltip when only private locations are available. --- .../action_bar/action_bar.tsx | 41 +++++++++++++++--- .../hooks/use_run_once_errors.ts | 12 ++++-- .../monitor_list/columns/test_now_col.tsx | 42 +++---------------- .../overview/monitor_list/translations.ts | 32 ++++++++++++++ 4 files changed, 80 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx index f0e69395f6075..0cae34a05e35b 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/action_bar/action_bar.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback, useContext, useState, useEffect } from 'react'; +import React, { useCallback, useContext, useState, useEffect, useRef } from 'react'; import { useParams, Redirect } from 'react-router-dom'; import { EuiFlexGroup, @@ -38,6 +38,11 @@ import { monitorManagementListSelector } from '../../../state/selectors'; import { kibanaService } from '../../../state/kibana_service'; +import { + PRIVATE_AVAILABLE_LABEL, + TEST_SCHEDULED_LABEL, +} from '../../overview/monitor_list/translations'; + export interface ActionBarProps { monitor: SyntheticsMonitor; isValid: boolean; @@ -63,9 +68,11 @@ export const ActionBar = ({ const [isSaving, setIsSaving] = useState(false); const [isSuccessful, setIsSuccessful] = useState(false); const [isPopoverOpen, setIsPopoverOpen] = useState(undefined); + const mouseMoveTimeoutIds = useRef<[number, number]>([0, 0]); const isReadOnly = monitor[ConfigKey.MONITOR_SOURCE_TYPE] === SourceType.PROJECT; const hasServiceManagedLocation = monitor.locations?.some((loc) => loc.isServiceManaged); + const isOnlyPrivateLocations = !locations.some((loc) => loc.isServiceManaged); const { data, status } = useFetcher(() => { if (!isSaving || !isValid) { @@ -139,11 +146,14 @@ export const ActionBar = ({ {!isValid && hasBeenSubmitted && VALIDATION_ERROR_LABEL} + {onTestNow && ( {/* Popover is used instead of EuiTooltip until the resolution of https://github.com/elastic/eui/issues/5604 */} onTestNow()} - onMouseEnter={() => { - setIsPopoverOpen(true); + onMouseOver={() => { + // We need this custom logic to display a popover even when button is disabled. + clearTimeout(mouseMoveTimeoutIds.current[1]); + if (mouseMoveTimeoutIds.current[0] === 0) { + mouseMoveTimeoutIds.current[0] = setTimeout(() => { + clearTimeout(mouseMoveTimeoutIds.current[1]); + setIsPopoverOpen(true); + }, 250) as unknown as number; + } }} - onMouseLeave={() => { - setIsPopoverOpen(false); + onMouseOut={() => { + // We need this custom logic to display a popover even when button is disabled. + clearTimeout(mouseMoveTimeoutIds.current[1]); + mouseMoveTimeoutIds.current[1] = setTimeout(() => { + clearTimeout(mouseMoveTimeoutIds.current[0]); + setIsPopoverOpen(false); + mouseMoveTimeoutIds.current = [0, 0]; + }, 100) as unknown as number; }} > {testRun ? RE_RUN_TEST_LABEL : RUN_TEST_LABEL} @@ -167,7 +190,13 @@ export const ActionBar = ({ isOpen={isPopoverOpen} > -

{TEST_NOW_DESCRIPTION}

+

+ {isTestRunInProgress + ? TEST_SCHEDULED_LABEL + : isOnlyPrivateLocations || (isValid && !hasServiceManagedLocation) + ? PRIVATE_AVAILABLE_LABEL + : TEST_NOW_DESCRIPTION} +

diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_run_once_errors.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_run_once_errors.ts index 916ca8c00b972..098154f4e20ce 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_run_once_errors.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/hooks/use_run_once_errors.ts @@ -22,6 +22,10 @@ export function useRunOnceErrors({ }) { const [locationErrors, setLocationErrors] = useState([]); const [runOnceServiceError, setRunOnceServiceError] = useState(null); + const publicLocations = useMemo( + () => (locations ?? []).filter((loc) => loc.isServiceManaged), + [locations] + ); useEffect(() => { setLocationErrors([]); @@ -43,16 +47,16 @@ export function useRunOnceErrors({ }, [serviceError]); const locationsById: Record = useMemo( - () => (locations as Locations).reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {}), - [locations] + () => (publicLocations as Locations).reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {}), + [publicLocations] ); const expectPings = - locations.length - (locationErrors ?? []).filter(({ locationId }) => !!locationId).length; + publicLocations.length - (locationErrors ?? []).filter(({ locationId }) => !!locationId).length; const hasBlockingError = !!runOnceServiceError || - (locationErrors?.length && locationErrors?.length === locations.length); + (locationErrors?.length && locationErrors?.length === publicLocations.length); const errorMessages = useMemo(() => { if (hasBlockingError) { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/test_now_col.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/test_now_col.tsx index 425d881e0141e..17e8047ac64c7 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/test_now_col.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/test_now_col.tsx @@ -6,12 +6,12 @@ */ import { EuiButtonIcon, EuiLoadingSpinner, EuiToolTip } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Ping } from '../../../../../../common/runtime_types'; import { testNowMonitorAction } from '../../../../state/actions'; import { testNowRunSelector, TestRunStats } from '../../../../state/reducers/test_now_runs'; +import * as labels from '../translations'; export const TestNowColumn = ({ monitorId, @@ -28,7 +28,7 @@ export const TestNowColumn = ({ if (selectedMonitor.monitor.fleet_managed) { return ( - + <>-- ); @@ -36,7 +36,7 @@ export const TestNowColumn = ({ if (!configId) { return ( - + <>-- ); @@ -54,45 +54,13 @@ export const TestNowColumn = ({ } return ( - + testNowClick()} isDisabled={!isTestNowCompleted} - aria-label={TEST_NOW_ARIA_LABEL} + aria-label={labels.TEST_NOW_ARIA_LABEL} /> ); }; - -export const TEST_NOW_ARIA_LABEL = i18n.translate( - 'xpack.synthetics.monitorList.testNow.AriaLabel', - { - defaultMessage: 'CLick to run test now', - } -); - -export const TEST_NOW_AVAILABLE_LABEL = i18n.translate( - 'xpack.synthetics.monitorList.testNow.available', - { - defaultMessage: 'Test now is only available for monitors added via Monitor Management.', - } -); - -export const PRIVATE_AVAILABLE_LABEL = i18n.translate( - 'xpack.synthetics.monitorList.testNow.available.private', - { - defaultMessage: `You can't currently test monitors running on private locations on demand.`, - } -); - -export const TEST_NOW_LABEL = i18n.translate('xpack.synthetics.monitorList.testNow.label', { - defaultMessage: 'Test now', -}); - -export const TEST_SCHEDULED_LABEL = i18n.translate( - 'xpack.synthetics.monitorList.testNow.scheduled', - { - defaultMessage: 'Test is already scheduled', - } -); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/translations.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/translations.ts index 402846b16c875..2f3bac51ce887 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/translations.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/translations.ts @@ -83,3 +83,35 @@ export const STATUS_ALERT_COLUMN = i18n.translate( export const TEST_NOW_COLUMN = i18n.translate('xpack.synthetics.monitorList.testNow.label', { defaultMessage: 'Test now', }); + +export const TEST_NOW_AVAILABLE_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.testNow.available', + { + defaultMessage: 'Test now is only available for monitors added via Monitor Management.', + } +); + +export const TEST_SCHEDULED_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.testNow.scheduled', + { + defaultMessage: 'Test is already scheduled', + } +); + +export const PRIVATE_AVAILABLE_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.testNow.available.private', + { + defaultMessage: `You can't currently test monitors running on private locations on demand.`, + } +); + +export const TEST_NOW_ARIA_LABEL = i18n.translate( + 'xpack.synthetics.monitorList.testNow.AriaLabel', + { + defaultMessage: 'Click to run test now', + } +); + +export const TEST_NOW_LABEL = i18n.translate('xpack.synthetics.monitorList.testNow.label', { + defaultMessage: 'Test now', +}); From 11588b31758fa95e095d8589c5b5bb68b2ad994c Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 21 Sep 2022 16:34:04 +0300 Subject: [PATCH 50/55] Fix bug (#141221) --- .../components/recent_cases/index.test.tsx | 36 ++++++++++++++++--- .../components/recent_cases/recent_cases.tsx | 8 ++++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx index 4ec853a0f9a24..46138fb354604 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx @@ -9,7 +9,12 @@ import React from 'react'; import { configure, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import RecentCases, { RecentCasesProps } from '.'; -import { AppMockRenderer, createAppMockRenderer, TestProviders } from '../../common/mock'; +import { + AppMockRenderer, + createAppMockRenderer, + noCasesCapabilities, + TestProviders, +} from '../../common/mock'; import { useGetCasesMockState } from '../../containers/mock'; import { useCurrentUser } from '../../common/lib/kibana/hooks'; import { useGetCases } from '../../containers/use_get_cases'; @@ -82,7 +87,7 @@ describe('RecentCases', () => { ); expect(useGetCasesMock).toHaveBeenCalledWith({ - filterOptions: { reporters: [] }, + filterOptions: { reporters: [], owner: ['securitySolution'] }, queryParams: { perPage: 2 }, }); }); @@ -95,7 +100,7 @@ describe('RecentCases', () => { ); expect(useGetCasesMock).toHaveBeenCalledWith({ - filterOptions: { reporters: [] }, + filterOptions: { reporters: [], owner: ['securitySolution'] }, queryParams: { perPage: 10 }, }); @@ -115,6 +120,7 @@ describe('RecentCases', () => { username: 'damaged_raccoon', }, ], + owner: ['securitySolution'], }, queryParams: { perPage: 10 }, }); @@ -126,6 +132,7 @@ describe('RecentCases', () => { expect(useGetCasesMock).toHaveBeenLastCalledWith({ filterOptions: { reporters: [], + owner: ['securitySolution'], }, queryParams: { perPage: 10 }, }); @@ -141,7 +148,7 @@ describe('RecentCases', () => { ); expect(useGetCasesMock).toHaveBeenCalledWith({ - filterOptions: { reporters: [] }, + filterOptions: { reporters: [], owner: ['securitySolution'] }, queryParams: { perPage: 10 }, }); @@ -160,8 +167,29 @@ describe('RecentCases', () => { username: 'elastic', }, ], + owner: ['securitySolution'], }, queryParams: { perPage: 10 }, }); }); + + it('sets all available solutions correctly', () => { + appMockRender = createAppMockRenderer({ owner: [] }); + /** + * We set securitySolutionCases capability to not have + * any access to cases. This tests that we get the owners + * that have at least read access. + */ + appMockRender.coreStart.application.capabilities = { + ...appMockRender.coreStart.application.capabilities, + securitySolutionCases: noCasesCapabilities(), + }; + + appMockRender.render(); + + expect(useGetCasesMock).toHaveBeenCalledWith({ + filterOptions: { reporters: [], owner: ['cases'] }, + queryParams: { perPage: 2 }, + }); + }); }); diff --git a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx index 44eee0c0b23f8..190972eeb9327 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx @@ -18,6 +18,8 @@ import { MarkdownRenderer } from '../markdown_editor'; import { FilterOptions } from '../../containers/types'; import { TruncatedText } from '../truncated_text'; import { initialData as initialGetCasesData, useGetCases } from '../../containers/use_get_cases'; +import { useAvailableCasesOwners } from '../app/use_available_owners'; +import { useCasesContext } from '../cases_context/use_cases_context'; const MarkdownContainer = styled.div` max-height: 150px; @@ -31,9 +33,13 @@ export interface RecentCasesProps { } export const RecentCasesComp = ({ filterOptions, maxCasesToShow }: RecentCasesProps) => { + const { owner } = useCasesContext(); + const availableSolutions = useAvailableCasesOwners(['read']); + const hasOwner = !!owner.length; + const { data = initialGetCasesData, isLoading: isLoadingCases } = useGetCases({ queryParams: { perPage: maxCasesToShow }, - filterOptions, + filterOptions: { ...filterOptions, owner: hasOwner ? owner : availableSolutions }, }); return isLoadingCases ? ( From 7767e3fffb2de53b056e151b687c1002570f36f9 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 21 Sep 2022 15:54:44 +0200 Subject: [PATCH 51/55] fix time shift with reduced time range tabification (#141076) Co-authored-by: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> --- .../indexpattern.test.ts | 36 +++++++++++++++++++ .../operations/definitions/count.tsx | 4 +-- .../indexpattern_datasource/to_expression.ts | 2 +- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts index 460b981846e48..c19338dd156f0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts @@ -1039,6 +1039,42 @@ describe('IndexPattern Data Source', () => { `); }); + it('should not add time shift to nested count metric', async () => { + const queryBaseState: IndexPatternPrivateState = { + currentIndexPatternId: '1', + layers: { + first: { + indexPatternId: '1', + columnOrder: ['col1'], + columns: { + col1: { + label: 'Count of records', + dataType: 'number', + isBucketed: false, + sourceField: '___records___', + operationType: 'count', + timeShift: '1h', + reducedTimeRange: '1m', + }, + }, + }, + }, + }; + + const ast = indexPatternDatasource.toExpression( + queryBaseState, + 'first', + indexPatterns + ) as Ast; + const filteredMetricAgg = (ast.chain[1].arguments.aggs[0] as Ast).chain[0].arguments; + const metricAgg = (filteredMetricAgg.customMetric[0] as Ast).chain[0].arguments; + const bucketAgg = (filteredMetricAgg.customBucket[0] as Ast).chain[0].arguments; + expect(filteredMetricAgg.timeShift[0]).toEqual('1h'); + expect(bucketAgg.timeWindow[0]).toEqual('1m'); + expect(metricAgg.timeWindow).toEqual(undefined); + expect(metricAgg.timeShift).toEqual(undefined); + }); + it('should put column formatters after calculated columns', async () => { const queryBaseState: IndexPatternPrivateState = { currentIndexPatternId: '1', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index bd083c1dfaff4..e2eedc5a2d3c6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -191,7 +191,7 @@ export const countOperation: OperationDefinition Date: Wed, 21 Sep 2022 09:59:28 -0400 Subject: [PATCH 52/55] [Guided onboarding] Setup guide panel component (#140836) --- .../public/components/guide_panel.styles.ts | 47 +++ .../public/components/guide_panel.test.tsx | 76 +++++ .../public/components/guide_panel.tsx | 308 ++++++++++++++++++ .../components/guide_panel_step.styles.ts | 25 ++ .../public/components/guide_panel_step.tsx | 99 ++++++ .../public/components/index.ts | 2 +- .../public/components/onboarding_button.tsx | 241 -------------- .../public/constants/observability.ts | 42 ++- .../public/constants/search.ts | 30 +- .../public/constants/security.ts | 31 +- .../guided_onboarding/public/plugin.tsx | 8 +- src/plugins/guided_onboarding/public/types.ts | 2 +- 12 files changed, 635 insertions(+), 276 deletions(-) create mode 100644 src/plugins/guided_onboarding/public/components/guide_panel.styles.ts create mode 100644 src/plugins/guided_onboarding/public/components/guide_panel.test.tsx create mode 100644 src/plugins/guided_onboarding/public/components/guide_panel.tsx create mode 100644 src/plugins/guided_onboarding/public/components/guide_panel_step.styles.ts create mode 100644 src/plugins/guided_onboarding/public/components/guide_panel_step.tsx delete mode 100644 src/plugins/guided_onboarding/public/components/onboarding_button.tsx diff --git a/src/plugins/guided_onboarding/public/components/guide_panel.styles.ts b/src/plugins/guided_onboarding/public/components/guide_panel.styles.ts new file mode 100644 index 0000000000000..1ba565c9caee0 --- /dev/null +++ b/src/plugins/guided_onboarding/public/components/guide_panel.styles.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { EuiThemeComputed } from '@elastic/eui'; +import { css } from '@emotion/react'; + +/** + * + * Style overrides for the setup guide dropdown panel. + * There is currently no existing EUI component that fully supports what we need. + * In order to leverage a11y features, we are using the EuiFlyout and applying customizations + * See https://github.com/elastic/eui/issues/6241 for more details + */ +export const getGuidePanelStyles = (euiTheme: EuiThemeComputed) => ({ + flyoutOverrides: { + flyoutContainer: css` + top: 55px !important; + bottom: 25px !important; + right: 128px; + border-radius: 6px; + width: 480px; + height: auto; + animation: euiModal 350ms cubic-bezier(0.34, 1.61, 0.7, 1); + box-shadow: none; + "@media only screen and (max-width: 574px)": { + right: 25px; + width: 100%; + }, + `, + flyoutBody: css` + .euiFlyoutBody__overflowContent { + width: 480px; + padding-top: 10px; + } + `, + flyoutFooter: css` + border-radius: 0 0 6px 6px; + background: ${euiTheme.colors.ghost}; + padding: 24px 30px; + `, + }, +}); diff --git a/src/plugins/guided_onboarding/public/components/guide_panel.test.tsx b/src/plugins/guided_onboarding/public/components/guide_panel.test.tsx new file mode 100644 index 0000000000000..5eaf24163d2ae --- /dev/null +++ b/src/plugins/guided_onboarding/public/components/guide_panel.test.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { act } from 'react-dom/test-utils'; +import React from 'react'; + +import { applicationServiceMock } from '@kbn/core-application-browser-mocks'; +import { httpServiceMock } from '@kbn/core/public/mocks'; +import { HttpSetup } from '@kbn/core/public'; + +import { apiService } from '../services/api'; +import { guidesConfig } from '../constants/guides_config'; +import { GuidePanel } from './guide_panel'; +import { registerTestBed, TestBed } from '@kbn/test-jest-helpers'; + +const applicationMock = applicationServiceMock.createStartContract(); + +const getGuidePanel = () => () => { + return ; +}; + +describe('GuidePanel', () => { + let httpClient: jest.Mocked; + let testBed: TestBed; + + beforeEach(async () => { + httpClient = httpServiceMock.createStartContract({ basePath: '/base/path' }); + // Set default state on initial request (no active guides) + httpClient.get.mockResolvedValue({ + state: { activeGuide: 'unset', activeStep: 'unset' }, + }); + apiService.setup(httpClient); + + await act(async () => { + const GuidePanelComponent = getGuidePanel(); + testBed = registerTestBed(GuidePanelComponent)(); + }); + + testBed.component.update(); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + test('it should be disabled in there is no active guide', async () => { + const { exists } = testBed; + expect(exists('disabledGuideButton')).toBe(true); + expect(exists('guideButton')).toBe(false); + expect(exists('guidePanel')).toBe(false); + }); + + test('it should be enabled if there is an active guide', async () => { + const { exists, component, find } = testBed; + + await act(async () => { + // Enable the "search" guide + await apiService.updateGuideState({ + activeGuide: 'search', + activeStep: guidesConfig.search.steps[0].id, + }); + }); + + component.update(); + + expect(exists('disabledGuideButton')).toBe(false); + expect(exists('guideButton')).toBe(true); + expect(exists('guidePanel')).toBe(true); + expect(find('guidePanelStep').length).toEqual(guidesConfig.search.steps.length); + }); +}); diff --git a/src/plugins/guided_onboarding/public/components/guide_panel.tsx b/src/plugins/guided_onboarding/public/components/guide_panel.tsx new file mode 100644 index 0000000000000..f32f55e42b340 --- /dev/null +++ b/src/plugins/guided_onboarding/public/components/guide_panel.tsx @@ -0,0 +1,308 @@ +/* + * Copyright 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, useEffect, useRef } from 'react'; +import { + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiFlyoutFooter, + EuiButton, + EuiText, + EuiProgress, + EuiHorizontalRule, + EuiSpacer, + htmlIdGenerator, + EuiButtonEmpty, + EuiTitle, + EuiLink, + EuiFlexGroup, + EuiFlexItem, + useEuiTheme, +} from '@elastic/eui'; + +import { ApplicationStart } from '@kbn/core-application-browser'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { guidesConfig } from '../constants/guides_config'; +import type { GuideConfig, StepStatus, GuidedOnboardingState, StepConfig } from '../types'; +import type { ApiService } from '../services/api'; + +import { GuideStep } from './guide_panel_step'; +import { getGuidePanelStyles } from './guide_panel.styles'; + +interface GuidePanelProps { + api: ApiService; + application: ApplicationStart; +} + +const getConfig = (state?: GuidedOnboardingState): GuideConfig | undefined => { + if (state?.activeGuide && state.activeGuide !== 'unset') { + return guidesConfig[state.activeGuide]; + } + + return undefined; +}; + +const getCurrentStep = ( + steps?: StepConfig[], + state?: GuidedOnboardingState +): number | undefined => { + if (steps && state?.activeStep) { + const activeStepIndex = steps.findIndex((step: StepConfig) => step.id === state.activeStep); + if (activeStepIndex > -1) { + return activeStepIndex + 1; + } + + return undefined; + } +}; + +const getStepStatus = (steps: StepConfig[], stepIndex: number, activeStep?: string): StepStatus => { + const activeStepIndex = steps.findIndex((step: StepConfig) => step.id === activeStep); + + if (activeStepIndex < stepIndex) { + return 'incomplete'; + } + + if (activeStepIndex === stepIndex) { + return 'in_progress'; + } + + return 'complete'; +}; + +export const GuidePanel = ({ api, application }: GuidePanelProps) => { + const { euiTheme } = useEuiTheme(); + const [isGuideOpen, setIsGuideOpen] = useState(false); + const [guideState, setGuideState] = useState(undefined); + const isFirstRender = useRef(true); + + const styles = getGuidePanelStyles(euiTheme); + + const toggleGuide = () => { + setIsGuideOpen((prevIsGuideOpen) => !prevIsGuideOpen); + }; + + const navigateToStep = (step: StepConfig) => { + setIsGuideOpen(false); + if (step.location) { + application.navigateToApp(step.location.appID, { path: step.location.path }); + } + }; + + const navigateToLandingPage = () => { + setIsGuideOpen(false); + application.navigateToApp('home', { path: '#getting_started' }); + }; + + useEffect(() => { + const subscription = api.fetchGuideState$().subscribe((newState) => { + if ( + guideState?.activeGuide !== newState.activeGuide || + guideState?.activeStep !== newState.activeStep + ) { + if (isFirstRender.current) { + isFirstRender.current = false; + } else { + setIsGuideOpen(true); + } + } + setGuideState(newState); + }); + return () => subscription.unsubscribe(); + }, [api, guideState?.activeGuide, guideState?.activeStep]); + + const guideConfig = getConfig(guideState); + + // TODO handle loading, error state + // https://github.com/elastic/kibana/issues/139799, https://github.com/elastic/kibana/issues/139798 + if (!guideConfig) { + return ( + + {i18n.translate('guidedOnboarding.disabledGuidedSetupButtonLabel', { + defaultMessage: 'Setup guide', + })} + + ); + } + + const currentStep = getCurrentStep(guideConfig.steps, guideState); + + return ( + <> + + {currentStep + ? i18n.translate('guidedOnboarding.guidedSetupStepButtonLabel', { + defaultMessage: 'Setup guide: Step {currentStep}', + values: { + currentStep, + }, + }) + : i18n.translate('guidedOnboarding.guidedSetupButtonLabel', { + defaultMessage: 'Setup guide', + })} + + + {isGuideOpen && ( + + + + {i18n.translate('guidedOnboarding.dropdownPanel.backToGuidesLink', { + defaultMessage: 'Back to guides', + })} + + + +

{guideConfig?.title}

+
+ + + +
+ + +
+ +

{guideConfig?.description}

+
+ + {guideConfig.docs && ( + <> + + + + {guideConfig.docs.text} + + + + )} + + + + {/* + TODO: Progress bar should only show after the first step has been started + We need to make changes to the state itself in order to support this + */} + + + + + + + {guideConfig?.steps.map((step, index, steps) => { + const accordionId = htmlIdGenerator(`accordion${index}`)(); + const stepStatus = getStepStatus(steps, index, guideState?.activeStep); + + return ( + + ); + })} +
+
+ + + + + {/* TODO: Implement exit guide modal - https://github.com/elastic/kibana/issues/139804 */} + {}}> + {i18n.translate('guidedOnboarding.dropdownPanel.footer.exitGuideButtonLabel', { + defaultMessage: 'Exit setup guide', + })} + + + + + + + {i18n.translate('guidedOnboarding.dropdownPanel.footer.feedbackLabel', { + defaultMessage: 'feedback', + })} + + ), + }} + /> + + + + + + + {i18n.translate( + 'guidedOnboarding.dropdownPanel.footer.helpTextDescription', + { + defaultMessage: 'here to help', + } + )} + + ), + }} + /> + + + + +
+ )} + + ); +}; diff --git a/src/plugins/guided_onboarding/public/components/guide_panel_step.styles.ts b/src/plugins/guided_onboarding/public/components/guide_panel_step.styles.ts new file mode 100644 index 0000000000000..498059564e6ea --- /dev/null +++ b/src/plugins/guided_onboarding/public/components/guide_panel_step.styles.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { EuiThemeComputed } from '@elastic/eui'; +import { css } from '@emotion/react'; + +export const getGuidePanelStepStyles = (euiTheme: EuiThemeComputed) => ({ + stepNumber: css` + width: 24px; + height: 24px; + border-radius: 50%; + border: 2px solid ${euiTheme.colors.success}; + font-weight: ${euiTheme.font.weight.medium}; + text-align: center; + line-height: 1.4; + `, + stepTitle: css` + font-weight: ${euiTheme.font.weight.bold}; + `, +}); diff --git a/src/plugins/guided_onboarding/public/components/guide_panel_step.tsx b/src/plugins/guided_onboarding/public/components/guide_panel_step.tsx new file mode 100644 index 0000000000000..e6a300b6b6742 --- /dev/null +++ b/src/plugins/guided_onboarding/public/components/guide_panel_step.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { + EuiButton, + EuiText, + EuiAccordion, + EuiHorizontalRule, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + useEuiTheme, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; +import type { StepStatus, StepConfig } from '../types'; +import { getGuidePanelStepStyles } from './guide_panel_step.styles'; + +interface GuideStepProps { + accordionId: string; + stepStatus: StepStatus; + stepConfig: StepConfig; + stepNumber: number; + navigateToStep: (step: StepConfig) => void; +} + +export const GuideStep = ({ + accordionId, + stepStatus, + stepNumber, + stepConfig, + navigateToStep, +}: GuideStepProps) => { + const { euiTheme } = useEuiTheme(); + const styles = getGuidePanelStepStyles(euiTheme); + + const buttonContent = ( + + + {stepStatus === 'complete' ? ( + + ) : ( + {stepNumber} + )} + + + + {stepConfig.title} + + + + ); + + return ( +
+ + <> + + + +
    + {stepConfig.descriptionList.map((description, index) => { + return
  • {description}
  • ; + })} +
+
+ + + {stepStatus === 'in_progress' && ( + + + navigateToStep(stepConfig)} fill> + {/* TODO: Support for conditional "Continue" button label if user revists a step - https://github.com/elastic/kibana/issues/139752 */} + {i18n.translate('guidedOnboarding.dropdownPanel.startStepButtonLabel', { + defaultMessage: 'Start', + })} + + + + )} + +
+ + +
+ ); +}; diff --git a/src/plugins/guided_onboarding/public/components/index.ts b/src/plugins/guided_onboarding/public/components/index.ts index 131e5c328e97e..e13e9f105158a 100644 --- a/src/plugins/guided_onboarding/public/components/index.ts +++ b/src/plugins/guided_onboarding/public/components/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export { GuidedOnboardingButton } from './onboarding_button'; +export { GuidePanel } from './guide_panel'; diff --git a/src/plugins/guided_onboarding/public/components/onboarding_button.tsx b/src/plugins/guided_onboarding/public/components/onboarding_button.tsx deleted file mode 100644 index 8dde62411f1c1..0000000000000 --- a/src/plugins/guided_onboarding/public/components/onboarding_button.tsx +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React, { useState, useEffect, useRef } from 'react'; -import { css } from '@emotion/react'; -import { - EuiPopover, - EuiPopoverTitle, - EuiPopoverFooter, - EuiButton, - EuiText, - EuiProgress, - EuiAccordion, - EuiHorizontalRule, - EuiSpacer, - EuiTextColor, - htmlIdGenerator, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - useEuiTheme, - EuiButtonEmpty, - EuiTitle, -} from '@elastic/eui'; - -import { ApplicationStart } from '@kbn/core-application-browser'; -import { HttpStart } from '@kbn/core-http-browser'; -import { i18n } from '@kbn/i18n'; -import { guidesConfig } from '../constants/guides_config'; -import type { GuideConfig, StepStatus, GuidedOnboardingState, StepConfig } from '../types'; -import type { ApiService } from '../services/api'; - -interface Props { - api: ApiService; - application: ApplicationStart; - http: HttpStart; -} - -const getConfig = (state?: GuidedOnboardingState): GuideConfig | undefined => { - if (state?.activeGuide && state.activeGuide !== 'unset') { - return guidesConfig[state.activeGuide]; - } - - return undefined; -}; - -const getStepLabel = (steps?: StepConfig[], state?: GuidedOnboardingState): string => { - if (steps && state?.activeStep) { - const activeStepIndex = steps.findIndex((step: StepConfig) => step.id === state.activeStep); - if (activeStepIndex > -1) { - return `: Step ${activeStepIndex + 1}`; - } - } - return ''; -}; - -const getStepStatus = (steps: StepConfig[], stepIndex: number, activeStep?: string): StepStatus => { - const activeStepIndex = steps.findIndex((step: StepConfig) => step.id === activeStep); - if (activeStepIndex < stepIndex) { - return 'incomplete'; - } - if (activeStepIndex === stepIndex) { - return 'in_progress'; - } - return 'complete'; -}; - -export const GuidedOnboardingButton = ({ api, application, http }: Props) => { - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - - const [guidedOnboardingState, setGuidedOnboardingState] = useState< - GuidedOnboardingState | undefined - >(undefined); - - const firstRender = useRef(true); - - useEffect(() => { - const subscription = api.fetchGuideState$().subscribe((newState) => { - if ( - guidedOnboardingState?.activeGuide !== newState.activeGuide || - guidedOnboardingState?.activeStep !== newState.activeStep - ) { - if (firstRender.current) { - firstRender.current = false; - } else { - setIsPopoverOpen(true); - } - } - setGuidedOnboardingState(newState); - }); - return () => subscription.unsubscribe(); - }, [api, guidedOnboardingState?.activeGuide, guidedOnboardingState?.activeStep]); - - const { euiTheme } = useEuiTheme(); - - const togglePopover = () => { - setIsPopoverOpen((prevIsPopoverOpen) => !prevIsPopoverOpen); - }; - - const popoverContainerCss = css` - width: 400px; - `; - - const statusCircleCss = ({ status }: { status: StepStatus }) => css` - width: 24px; - height: 24px; - border-radius: 32px; - ${(status === 'complete' || status === 'in_progress') && - `background-color: ${euiTheme.colors.success};`} - ${status === 'incomplete' && - ` - border: 2px solid ${euiTheme.colors.lightShade}; - `} - `; - - const guideConfig = getConfig(guidedOnboardingState); - const stepLabel = getStepLabel(guideConfig?.steps, guidedOnboardingState); - - const navigateToStep = (step: StepConfig) => { - setIsPopoverOpen(false); - if (step.location) { - application.navigateToApp(step.location.appID, { path: step.location.path }); - } - }; - - return guideConfig ? ( - - {i18n.translate('guidedOnboarding.guidedSetupButtonLabel', { - defaultMessage: 'Guided setup{stepLabel}', - values: { - stepLabel, - }, - })} -
- } - isOpen={isPopoverOpen} - closePopover={() => setIsPopoverOpen(false)} - anchorPosition="downRight" - hasArrow={false} - offset={10} - panelPaddingSize="l" - > - - {}} - iconSide="left" - iconType="arrowLeft" - isDisabled={true} - flush="left" - > - {i18n.translate('guidedOnboarding.dropdownPanel.backToGuidesLink', { - defaultMessage: 'Back to guides', - })} - - -

{guideConfig?.title}

-
-
- -
- -

{guideConfig?.description}

-
- - - - - {guideConfig?.steps.map((step, index, steps) => { - const accordionId = htmlIdGenerator(`accordion${index}`)(); - - const stepStatus = getStepStatus(steps, index, guidedOnboardingState?.activeStep); - const buttonContent = ( - - - - {stepStatus} - {stepStatus === 'complete' && } - - - {step.title} - - ); - - return ( -
- - <> - - {step.description} - - {stepStatus === 'in_progress' && ( - - - navigateToStep(step)} fill> - {/* TODO: Support for conditional "Continue" button label if user revists a step */} - {i18n.translate('guidedOnboarding.dropdownPanel.startStepButtonLabel', { - defaultMessage: 'Start', - })} - - - - )} - - - - {/* Do not show horizontal rule for last item */} - {guideConfig.steps.length - 1 !== index && } -
- ); - })} - - - -

- {i18n.translate('guidedOnboarding.dropdownPanel.footerDescription', { - defaultMessage: `Got questions? We're here to help.`, - })} -

-
-
-
-
- - ) : ( - - Guided setup - - ); -}; diff --git a/src/plugins/guided_onboarding/public/constants/observability.ts b/src/plugins/guided_onboarding/public/constants/observability.ts index 72d2a70dfa44d..fb60c71f8ee17 100644 --- a/src/plugins/guided_onboarding/public/constants/observability.ts +++ b/src/plugins/guided_onboarding/public/constants/observability.ts @@ -20,38 +20,56 @@ export const observabilityConfig: GuideConfig = { { id: 'add_data', title: 'Add data', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'rules', title: 'Customize your alerting rules', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'infrastructure', title: 'View infrastructure details', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'explore', title: 'Explore Discover and Dashboards', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'tour', title: 'Tour Observability', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'do_more', title: 'Do more with Observability', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, ], }; diff --git a/src/plugins/guided_onboarding/public/constants/search.ts b/src/plugins/guided_onboarding/public/constants/search.ts index 8f6ff8fb7600b..f93beff593fb8 100644 --- a/src/plugins/guided_onboarding/public/constants/search.ts +++ b/src/plugins/guided_onboarding/public/constants/search.ts @@ -10,7 +10,7 @@ import type { GuideConfig } from '../types'; export const searchConfig: GuideConfig = { title: 'Search my data', - description: `We'll help you build world-class search experiences with your data.`, + description: `We'll help you build world-class search experiences with your data, using Elastic's out-of-the-box web crawler, connectors, and our robust APIs. Gain deep insights from the built-in search analytics and use that data to inform changes to relevance.`, docs: { text: 'Enterprise Search 101 Documentation', url: 'example.com', @@ -19,8 +19,11 @@ export const searchConfig: GuideConfig = { { id: 'add_data', title: 'Add data', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], location: { appID: 'guidedOnboardingExample', path: 'stepOne', @@ -29,8 +32,11 @@ export const searchConfig: GuideConfig = { { id: 'search_experience', title: 'Build a search experience', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], location: { appID: 'guidedOnboardingExample', path: 'stepTwo?showTour=true', @@ -39,14 +45,20 @@ export const searchConfig: GuideConfig = { { id: 'optimize', title: 'Optimize your search relevance', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'review', title: 'Review your search analytics', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, ], }; diff --git a/src/plugins/guided_onboarding/public/constants/security.ts b/src/plugins/guided_onboarding/public/constants/security.ts index f8447f81dc019..84b4e107674ad 100644 --- a/src/plugins/guided_onboarding/public/constants/security.ts +++ b/src/plugins/guided_onboarding/public/constants/security.ts @@ -16,28 +16,47 @@ export const securityConfig: GuideConfig = { { id: 'add_data', title: 'Add and view your data', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'rules', title: 'Turn on rules', - description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'alerts', title: 'View Alerts', - description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'cases', title: 'Cases and investigations', - description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, { id: 'do_more', title: 'Do more with Elastic Security', - description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + descriptionList: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.', + 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.', + ], }, ], }; diff --git a/src/plugins/guided_onboarding/public/plugin.tsx b/src/plugins/guided_onboarding/public/plugin.tsx index 9b2e95656cb80..902acaa899e3a 100755 --- a/src/plugins/guided_onboarding/public/plugin.tsx +++ b/src/plugins/guided_onboarding/public/plugin.tsx @@ -16,7 +16,6 @@ import { Plugin, CoreTheme, ApplicationStart, - HttpStart, PluginInitializerContext, } from '@kbn/core/public'; @@ -26,7 +25,7 @@ import { GuidedOnboardingPluginSetup, GuidedOnboardingPluginStart, } from './types'; -import { GuidedOnboardingButton } from './components'; +import { GuidePanel } from './components'; import { ApiService, apiService } from './services/api'; export class GuidedOnboardingPlugin @@ -56,7 +55,6 @@ export class GuidedOnboardingPlugin theme$: theme.theme$, api: apiService, application, - http, }), }); @@ -73,18 +71,16 @@ export class GuidedOnboardingPlugin theme$, api, application, - http, }: { targetDomElement: HTMLElement; theme$: Rx.Observable; api: ApiService; application: ApplicationStart; - http: HttpStart; }) { ReactDOM.render( - + , targetDomElement diff --git a/src/plugins/guided_onboarding/public/types.ts b/src/plugins/guided_onboarding/public/types.ts index 1e9fd7ab76574..7925fa8ae69d7 100755 --- a/src/plugins/guided_onboarding/public/types.ts +++ b/src/plugins/guided_onboarding/public/types.ts @@ -26,7 +26,7 @@ export type StepStatus = 'incomplete' | 'complete' | 'in_progress'; export interface StepConfig { id: string; title: string; - description: string; + descriptionList: string[]; location?: { appID: string; path: string; From 7be5ac42a075f572f3c808c96d6f557b33de52da Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 21 Sep 2022 07:32:36 -0700 Subject: [PATCH 53/55] [artifacts/cft] Soft fail on timeout (#141180) Co-authored-by: Jonathan Budzenski --- .buildkite/pipelines/artifacts.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pipelines/artifacts.yml b/.buildkite/pipelines/artifacts.yml index b6d3cc9fc9b14..e133c4b569317 100644 --- a/.buildkite/pipelines/artifacts.yml +++ b/.buildkite/pipelines/artifacts.yml @@ -75,6 +75,7 @@ steps: label: 'Cloud Deployment' soft_fail: - exit_status: 255 + - exit_status: -1 agents: queue: n2-2 timeout_in_minutes: 30 From ee4b451ed49375bcde5066a519bccb52568dfcde Mon Sep 17 00:00:00 2001 From: Giorgos Bamparopoulos Date: Wed, 21 Sep 2022 15:38:13 +0100 Subject: [PATCH 54/55] [APM] Synthtrace - Add service.name in metricsetPicker for breakdown metrics (#140256) * Add service.name in metricsetPicker for breakdown metrics * Run cypress tests on synthtrace changes --- .buildkite/scripts/pipelines/pull_request/pipeline.ts | 2 +- .../src/lib/apm/processors/get_breakdown_metrics.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.ts b/.buildkite/scripts/pipelines/pull_request/pipeline.ts index 59cac2eaf5259..617a80524e6dd 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.ts +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.ts @@ -90,7 +90,7 @@ const uploadPipeline = (pipelineContent: string | object) => { } if ( - (await doAnyChangesMatch([/^x-pack\/plugins\/apm/])) || + (await doAnyChangesMatch([/^x-pack\/plugins\/apm/, /^packages\/kbn-apm-synthtrace/])) || GITHUB_PR_LABELS.includes('ci:all-cypress-suites') ) { pipeline.push(getPipeline('.buildkite/pipelines/pull_request/apm_cypress.yml')); diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts b/packages/kbn-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts index 1772b5f655713..26a908bd085ab 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/processors/get_breakdown_metrics.ts @@ -105,15 +105,16 @@ export function getBreakdownMetrics(events: ApmFields[]) { lastMeasurement = timestamp; } + const instance = pickBy(event, instancePicker); + const key = { '@timestamp': event['@timestamp']! - (event['@timestamp']! % (30 * 1000)), 'transaction.type': transaction['transaction.type'], 'transaction.name': transaction['transaction.name'], ...pickBy(event, metricsetPicker), + ...instance, }; - const instance = pickBy(event, instancePicker); - const metricsetId = objectHash(key); let metricset = metricsets.get(metricsetId); @@ -121,7 +122,6 @@ export function getBreakdownMetrics(events: ApmFields[]) { if (!metricset) { metricset = { ...key, - ...instance, 'processor.event': 'metric', 'processor.name': 'metric', 'metricset.name': `span_breakdown`, From c713550e170205fc9f297a67de5a7019ac5e6aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:44:06 +0200 Subject: [PATCH 55/55] [Guided onboarding] Added plugin's README (#141219) * [Guided onboarding] Documentation * [Guided onboarding] Examples readme link * [CI] Auto-commit changed files from 'node scripts/build_plugin_list_docs' * Update src/plugins/guided_onboarding/README.md Co-authored-by: Alison Goryachev * [CI] Auto-commit changed files from 'node scripts/build_plugin_list_docs' * [Guided onboarding] Short info about config files Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Alison Goryachev --- docs/developer/plugin-list.asciidoc | 2 +- examples/guided_onboarding_example/README.md | 2 +- src/plugins/guided_onboarding/README.md | 74 ++++++++++++++++++- .../public/services/helpers.ts | 2 +- 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index e4524b7fa7828..e84cc4c4ee0b0 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -177,7 +177,7 @@ for use in their own application. |{kib-repo}blob/{branch}/src/plugins/guided_onboarding/README.md[guidedOnboarding] -|A Kibana plugin +|This plugin contains the code for the Guided Onboarding project. Guided onboarding consists of guides for Solutions (Enterprise Search, Observability, Security) that can be completed as a checklist of steps. The guides help users to ingest their data and to navigate to the correct Solutions pages. |{kib-repo}blob/{branch}/src/plugins/home/README.md[home] diff --git a/examples/guided_onboarding_example/README.md b/examples/guided_onboarding_example/README.md index c00f5c7a4656c..544db5b5731e8 100755 --- a/examples/guided_onboarding_example/README.md +++ b/examples/guided_onboarding_example/README.md @@ -1,6 +1,6 @@ # guidedOnboardingExample -A Kibana plugin +This plugin contains code examples for the Guided Onboarding plugin. More information can be found in `KIBANA_FOLDER/src/plugins/guided_onboarding/README.md` --- diff --git a/src/plugins/guided_onboarding/README.md b/src/plugins/guided_onboarding/README.md index c0f16b034d043..1daa04d223e2b 100755 --- a/src/plugins/guided_onboarding/README.md +++ b/src/plugins/guided_onboarding/README.md @@ -1,9 +1,77 @@ -# guidedOnboarding +# Guided Onboarding -A Kibana plugin +This plugin contains the code for the Guided Onboarding project. Guided onboarding consists of guides for Solutions (Enterprise Search, Observability, Security) that can be completed as a checklist of steps. The guides help users to ingest their data and to navigate to the correct Solutions pages. + +The guided onboarding plugin includes a client-side code for the UI and the server side code for the internal API. The server-side code is not intended for external use. + +The client-side code registers a button in the Kibana header that controls the guided onboarding panel (checklist) depending on the current state. There is also an API service exposed from the client-side start contract. The API service is intended for external use by other plugins. --- ## Development -See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment. +1. To enable the UI, add `guidedOnboarding.ui: true` to the file `KIBANA_FOLDER/config/kibana.dev.yml`. + +2. Start Kibana with examples `yarn start --run-examples` to be able to see the guidedOnboardingExample plugin. + +3. Navigate to `/app/guidedOnboardingExample` to start a guide and check the button in the header. + +## API service +*Also see `KIBANA_FOLDER/examples/guided_onboarding_example` for code examples.* + +The guided onboarding plugin exposes an API service from its start contract that is intended to be used by other plugins. The API service allows consumers to access the current state of the guided onboarding process and manipulate it. + +To use the API service in your plugin, declare the guided onboarding plugin as a dependency in the file `kibana.json` of your plugin. Add the API service to your plugin's start dependencies to rely on the provided TypeScript interface: +``` +export interface AppPluginStartDependencies { + guidedOnboarding: GuidedOnboardingPluginStart; +} +``` +The API service is now available to your plugin in the setup lifecycle function of your plugin +``` +// startDependencies is of type AppPluginStartDependencies +const [coreStart, startDependencies] = await core.getStartServices(); +``` +or in the start lifecycle function of your plugin. +``` +public start(core: CoreStart, startDependencies: AppPluginStartDependencies) { + ... +} +``` + +### isGuideStepActive$(guideID: string, stepID: string): Observable\ +*Also see `KIBANA_FOLDER/examples/guided_onboarding_example/public/components/step_one.tsx`.* + +The API service exposes an Observable that contains a boolean value for the state of a specific guide step. For example, if your plugin needs to check if the "Add data" step of the Security guide is currently active, you could use the following code snippet. + +``` +const { guidedOnboardingApi } = guidedOnboarding; +const isDataStepActive = useObservable(guidedOnboardingApi!.isGuideStepActive$('security', 'add_data')); +useEffect(() => { + // do some logic depending on the step state +}, [isDataStepActive]); +``` + +Alternatively, you can subscribe to the Observable directly. +``` +useEffect(() => { + const subscription = guidedOnboardingApi?.isGuideStepActive$('security', 'add_data').subscribe((isDataStepACtive) => { + // do some logic depending on the step state + }); + return () => subscription?.unsubscribe(); +}, [guidedOnboardingApi]); +``` + +### completeGuideStep(guideID: string, stepID: string): Promise\<{ state: GuidedOnboardingState } | undefined\> +The API service exposes an async function to mark a guide step as completed. +If the specified guide step is not currently active, the function is a noop. The return value is `undefined` in that case, +otherwise an updated `GuidedOnboardingState` is returned *(This is WIP and will likely change in the 8.6 dev cycle)*. + +``` +await guidedOnboardingApi?.completeGuideStep('security', 'add_data'); +``` + +## Guides config +To use the API service, you need to know a guide ID (one of `search`, `observability`, `security`) and a step ID (for example, `add_data`, `search_experience`, `rules` etc). Refer to guides config files in the folder `./public/constants` for more information. + + diff --git a/src/plugins/guided_onboarding/public/services/helpers.ts b/src/plugins/guided_onboarding/public/services/helpers.ts index 81020adab0cd6..3eb0bfca9b751 100644 --- a/src/plugins/guided_onboarding/public/services/helpers.ts +++ b/src/plugins/guided_onboarding/public/services/helpers.ts @@ -9,7 +9,7 @@ import { guidesConfig } from '../constants/guides_config'; import { GuideConfig, StepConfig, UseCase } from '../types'; -const getGuideConfig = (guideID?: string): GuideConfig | undefined => { +export const getGuideConfig = (guideID?: string): GuideConfig | undefined => { if (guideID && Object.keys(guidesConfig).includes(guideID)) { return guidesConfig[guideID as UseCase]; }